Статья, объясняющая часто используемые алгоритмы шифрования и дешифрования в платежных проектах.
Статья, объясняющая часто используемые алгоритмы шифрования и дешифрования в платежных проектах.
Предисловие

Как платежное учреждение, большая часть передаваемых данных является очень конфиденциальной, например, идентификационный номер, номер банковской карты, пароль банковской карты и т. д. Как только эта информация будет перехвачена преступниками, банковские карты могут быть напрямую украдены, что приведет к огромным потерям для потребителей. Если информация, полученная преступниками, зашифрована и нет ключа для дешифрования, то для преступников эта информация — просто тарабарщина. В этом и заключается самый важный смысл шифрования.

В настоящее время наиболее используемое шифрование、Расшифроватьалгоритм Есть две основные категории:Симметричный алгоритм шифрованияиНет Симметричный алгоритм шифрования。Основное различие между ними заключается вшифрованиеи Расшифроватьизсекретный ключ Это соответствует?,последовательныйто естьсимметрияшифрование,不последовательныйто есть Нетсимметрияшифрование。симметрияшифрование常用издаAESшифрованиеалгоритм,Нет Симметричный алгоритм шифрования常用издаRSAшифрованиеалгоритм,Представлено ниже RSA шифрованиеалгоритмиAESшифрованиеалгоритм在支付项目中из应用。

RSA Это алгоритм асимметричного шифрования, который позволяет завершить расшифровку без передачи секретного ключа, избегая возможности взлома из-за прямой передачи секретного ключа при симметричном шифровании. риск。RSA Шифрование/дешифрованиепо паре пооткрытый ключизакрытый ключ组成изсекретный ключ Завершено вместешифрованиеи Расшифровать,открытый ключ общедоступен, используется для шифрования, скрытности ключда保密из,используется для Расшифровать。两者之间通过一定изалгоритмассоциация,Основная идея состоит в том, чтобы использовать сложность факторизации пары чрезвычайно больших целых чисел для обеспечения безопасности.

Процесс шифрования RSA

Предположим, что A — платежное учреждение.,B — торговец платежного учреждения,Первый乙之间需要руководитьданныеизпередача инфекции。Если вы хотитеданныеруководитьШифрование/дешифрование,тогда ты должен сначалагенерироватьключ:Первыйгенерироватьпарасекретный ключ(открытый ключизакрытый ключ),открытый ключ Отдать Б,закрытый ключ оставляет себе аналогично, B также порождает пару закрытых самцов; ключ,открытый ключ给Первый,закрытый ключ Держи это при себе. Конкретный процесс показан на рисунке ниже:

Понятносекретный ключ Тогда ты сможешь对передача инфекцииизданныеруководитьшифрование Понятно。данныепередача инфекциида双向из,Следовательно, шифрование/дешифрование в платежной индустрии также является двусторонним.,Конкретные шаги заключаются в следующем:

1) B использует открытый ключ A для шифрования передаваемых данных и отправляет зашифрованные данные A;

2) А получает зашифрованные данные от Б и расшифровывает их с помощью своего закрытого ключа;

3) А шифрует обработанные данные с помощью открытого ключа Б и возвращает их Б;

4) B принимает возвращенные данные и расшифровывает их с помощью своего закрытого ключа.

Вышеуказанные шаги представляют собой относительно стандартный процесс шифрования/дешифрования для платежного учреждения.,Первый乙双方分别использовать对方изоткрытый ключ шифрования, затем используйте свой собственный закрытый ключ Расшифровать,Конкретный процесс показан на рисунке ниже:

Пример шифрования/дешифрования алгоритма RSA

JDK Уже упаковано RSA Шифрование/дешифрованиеизметод,Если вы хотитеданные Шифрование/дешифрование,тогда тебе нужно сначалагенерироватьпарасекретный ключ。генерироватьключиз代码Как показано ниже:

Язык кода:javascript
копировать
package org.sang.utils;

import java.security.*;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class keyPairGenUtil {
    // Размер ключа
    public static int KEY_LENGTH = 1024; 
    // тип алгоритма
    public static String ALGORITHM_TYPE = "RSA"; 
     
    public static Map<String, String> genkeyPair() throws NoSuchAlgorithmException {
        // хранилищеоткрытый ключизакрытый ключ
        Map<String, String> keyPairMap = new HashMap<>();
        // для RSA алгоритмсоздаватьkeyPairGenerator объект
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM_TYPE);
        // Создайте надежный источник случайных чисел
        SecureRandom secureRandom = new SecureRandom();
        // Инициализируйте keyPairGenerator со случайным источником данных. объект
        keyPairGenerator.initialize(KEY_LENGTH, secureRandom);
        // Создать пару ключей
        KeyPair keypair = keyPairGenerator.generateKeyPair();
        // получатьоткрытый ключ
        PublicKey publicKey = keypair.getPublic();
        // получатьзакрытый ключ
        PrivateKey privateKey = keypair.getPrivate();
        // использовать Base64 Воляоткрытый ключизакрытый ключконвертировать для строки
        String publicKeyStr = Base64.getEncoder().encodeToString(publicKey.getEncoded());
        String privateKeyStr = Base64.getEncoder().encodeToString(privateKey.getEncoded());
        keyPairMap.put("publicKey", publicKeyStr);
        keyPairMap.put("privateKey", privateKeyStr);
        return keyPairMap;
    }
    
}

генерироватьоткрытый ключизакрытый ключ Тогда ты сможешьшифрование Расшифровать Понятно,Пример Шифования/дешифрования выглядит так:

Язык кода:javascript
копировать
package org.sang.utils;

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class RSAUtil {

    public static String encrypt(String data, String publicKey) throws Exception {
        // использоватьBase64 Кодированный открытый парсинг ключей для двоичных файлов
        byte[] publicKeyByte = Base64.getDecoder().decode(publicKey);
        // получатьоткрытый ключ
        PublicKey pubKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyByte));
        // шифрованиеданные
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE,pubKey);
        // получатьшифрование后изданные        return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes()));
    }

    public static String decrypt(String data, String privateKey) throws Exception{
        // Воля Base64 编码иззакрытый парсинг ключей для двоичных файлов
        byte[] privateKeyByte = Base64.getDecoder().decode(privateKey);
        // использовать Base64 шифрованные, полученные после анализа
        byte[] dataByte = Base64.getDecoder().decode(data.getBytes());
        // получатьзакрытый ключ
        PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKeyByte));
        // RSA Расшифровать
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        // получать Расшифровать后изданные
        return new String(cipher.doFinal(dataByte));
    }
}
Тест шифрования/дешифрования алгоритма RSA

тогда напишитестзавершение занятийгенерироватьмужскойзакрытый ключи сделать банковский переводданныеруководитьшифрованиеи Расшифроватьизтестметод,Как показано ниже:

Язык кода:javascript
копировать
package org.sang.test;

import org.sang.utils.KeyPairGenUtil;
import org.sang.utils.RSAUtil;

import java.util.Map;

public class RSATest {

    public static void main(String[] args) throws Exception {
        Map<String, String> keyPairMap = KeyPairGenUtil.genkeyPair();
        String publicKey = keyPairMap.get("publicKey");
        System.out.println("publicKey="+publicKey);
        String privateKey = keyPairMap.get("privateKey");
        System.out.println("privateKey="+privateKey);
        String jsonData = "{\"fromCardNum\": \"622135689832498329\", \"payAmount\": 1000.00, \"toCardNum\": \"623269874369721685\"}";
        // временная метка начала шифрования
        long encryptStartTime = System.currentTimeMillis();
        String encryptData = RSAUtil.encrypt(jsonData, publicKey);
        // Расшифровать временную метку окончания
        long encryptEndTime = System.currentTimeMillis();
        System.out.println("Время шифрования алгоритма RSA:"+(encryptEndTime-encryptStartTime)+"ms");
        System.out.println("encryptData="+encryptData);
        // Расшифровать временную метку начала
        long decryptStartTime = System.currentTimeMillis();
        String decryptData = RSAUtil.decrypt(encryptData, privateKey);
        // Расшифровать временную метку окончания
        long decryptEndTime = System.currentTimeMillis();
        System.out.println("Расшифроватькропотливый:"+(decryptEndTime-decryptStartTime)+"ms");
        System.out.println("decryptData="+decryptData);
    }
}

бегать RSATest в классе main метод,можно увидеть Успешно распечатано в консолиоткрытый ключ、закрытый ключа такжешифрованиеданныеи Расшифроватьданные,由此说明我们写изгенерироватьмужскойзакрытый ключи Нет никаких проблем с методом шифрования и дешифрования алгоритма RSA.

Язык кода:javascript
копировать
publicKey=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCcy+2sKc+lTYrFe4RuiNWc62VAPtueoPDFP3UzCmhBp+zbTRR5U6uXeGEmQrKzTrFCH2yoDoKaxdFOfnjmV94zrc54WUpTWI5XXOgSBrmFhJBqoBgkRDv7M3oNw5FHnGWXJZ+ydk3fZVrcvw5qJDucAkG90/JvAW+kwL0PuI//3wIDAQAB
privateKey=MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJzL7awpz6VNisV7hG6I1ZzrZUA+256g8MU/dTMKaEGn7NtNFHlTq5d4YSZCsrNOsUIfbKgOgprF0U5+eOZX3jOtznhZSlNYjldc6BIGuYWEkGqgGCREO/szeg3DkUecZZcln7J2Td9lWty/DmokO5wCQb3T8m8Bb6TAvQ+4j//fAgMBAAECgYA3+r7CJrNRyxtuYijn5caOHaSqiUaTndYYNg27yU1rk26G5UAYCP1MONhGdq2iQsgaWWnLnlKWu2V85r53TouvzH1dmnR/s9mguVbjhYYsQ7zTbbAjQSImtNcWfkoGpPMR7uglkHfUlX16xF9iRfZN5pcZm/Sp8nQ7wVVXkIUBIQJBANFUiKhIlR7us+xL1Je7ZxgRg+KaIs7MDATNKtcf5FiJx0QHFvi0ezpDHIvBXhVIYgVm7EYOiEYCzb06jweZgAkCQQC/wQ1uawneOpobg76OVNGH28G1upC6xD+LeuSSU4e7Z3+YfJ1o1u83IJagNQNsDXb8S/gklw1R829iYQj0DCqnAkEAkcItDhDMVSedfRIoTCcf2DCKBwWQ6zJFxCoghH8ef1Agwou1QSRbEeydOetBWcx3BI/wQa/oz+cv322hHoeSEQJBAJm/7UkPwkXRrydIp03wbGEGr3dLNCjMmjb4PrWlDDwTbJeTs5MQY5ZMJvomB6xnz3PUZg7QnvmKu1CihU9JQhkCQD/dOHBP+/SN+NuBNJY9Ilj2sfkoH7psCAm57okSmTD6nJsqW9DPJJIXFnueKDN8SKg5QGmUri+swOFfqHPjpGM=
Затраченное время RSAалгоритмшифрования: 378 мс
encryptData=VGPHIUyMEHmipPai1Lz+jkET3QjTopIggS6I8AtvzeoIwTqR9ZWXy+fWaYN7L8na+bbd1NSpAx6V97Eb0doVTTwKtwBF7peG2ofFpz6ZqqLzo9ShpYKOY7CELFY/a40NOK8VxF7zz5iOdKVNgAGh7ei119bntApDkWypPA+cNk8=
Расшифроватькропотливый:6ms
decryptData={"fromCardNum": "622135689832498329", "payAmount": 1000.00, "toCardNum": "623269874369721685"}

здесьRSA алгоритмшифрованиевремя378ms, Расшифроватьвремя Понятно6ms, Конечно, время, необходимое для шифрования и дешифрования, также связано с длиной зашифрованного и расшифрованного контента.

AES-шифрование/дешифрование

AES да一种经典из Шифрование/дешифрованиеалгоритм,использоватьшифрование函数и Расшифроватьключ Приходить完成对明文изшифрование,Затемиспользовать相同изсекретный ключи对应из函数Приходить完成Расшифровать。AES из优点在于效率Нет常高,по сравнению сRSA алгоритмиз效率要高得多。AESалгоритм Процесс шифрования/дешифрования показан ниже:

AES Для шифрования и дешифрования требуется секретный ключ. Секретный ключ генерируется заранее. После того, как платежное учреждение сгенерирует ключ в соответствии с определенными правилами, он передается продавцу. Данные, предоставленные продавцом, необходимо зашифровать с помощью. секретный ключ. После того, как платежное учреждение получит зашифрованный текст. Используйте тот же секретный ключ для расшифровки.

AES-шифрование/дешифрование Пример
Язык кода:javascript
копировать
package org.sang.utils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class AESUtil {
    // обозначениетип алгоритма
    public static String AES = "AES";
    // Укажите длину ключа
    public static int KEY_LEN = 128;
    // Укажите формат кодировки
    public static String UTF_8 = "UTF-8";

    /**
     * генерировать AES секретный ключ
     * @return aesKey
     */
    public static String genAESKey() throws Exception{
        // структурасекретный ключгенерироватьустройство,обозначение AES алгоритм
        KeyGenerator keyGenerator = KeyGenerator.getInstance(AES);
        // генерировать一个обозначение位数из随机源,KEY_LEN=128 то есть 128 бит
        keyGenerator.init(KEY_LEN);
        // генерироватьсимметриясекретный ключ
        SecretKey secretKey = keyGenerator.generateKey();
        return Base64.getEncoder().encodeToString(secretKey.getEncoded());
    }

    /**
     * AES алгоритмшифрование
     * @param key секретный ключ
     * @param data обращатьсяшифрованиенитьданные     * @return encryptData
     */
    public static String encrypt(String key, String data) throws Exception{
        // Получить ключ
        SecretKey secretKey = new SecretKeySpec(Base64.getDecoder().decode(key.getBytes()), AES);
        // 根据обозначениеалгоритмгенерировать密码устройство
        Cipher cipher = Cipher.getInstance(AES);
        // Инициализировать шифр
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        // Воляшифрование содержимого преобразуется в массив байтов.
        byte[] byteData = data.getBytes(UTF_8);
        // Волябайтный массившифрование
        byte[] aesData = cipher.doFinal(byteData);
        return new String(Base64.getEncoder().encode(aesData));
    }

    /**
     * AES алгоритм Расшифровать
     * @param key секретный ключ
     * @param data обращаться Расшифроватьнитьданные
     * @return decryptData
     */
    public static String decrypt(String key, String data) throws Exception{
        // получать key
        SecretKey secretKey = new SecretKeySpec(Base64.getDecoder().decode(key.getBytes()), AES);
        // 根据обозначениеалгоритмгенерировать密码устройство
        Cipher cipher = Cipher.getInstance(AES);
        // Инициализировать шифр
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        // Воляшифрованиепреобразование контентадлямассив байтов,потому чтоданныедаиспользовать Base64 转换过из,так нужноиспользоватьBase64Расшифровать
        byte[] dataByte = Base64.getDecoder().decode(data.getBytes(UTF_8));
        // Расшифроватьмассив байтов
        byte[] decryptData = cipher.doFinal(dataByte);
        return new String(decryptData);
    }
    
}
AES-шифрование/дешифрование тест

Далее пишем тестовый тестовый класс с эффектом Шифрование/дешифрование AES. Код класса следующий:

Язык кода:javascript
копировать
package org.sang.test;

import org.sang.utils.AESUtil;

public class AESTest {

    public static void main(String[] args) throws Exception {
        String aesKey = AESUtil.genAESKey();
        System.out.println("aesKey:"+aesKey);
        String jsonData = "{\"fromCardNum\": \"622135689832498329\", \"payAmount\": 1000.00, \"toCardNum\": \"623269874369721685\"}";
        // AES временная метка начала алгоритмаалгоритма шифрования
        long aesEncryptStartTime = System.currentTimeMillis();
        String encryptData = AESUtil.encrypt(aesKey, jsonData);
        // AES временная метка алгоритма шифрованияалгоритм исправления
        long aesEncryptEndTime = System.currentTimeMillis();
        System.out.println("AESалгоритмшифрованиекропотливый:"+(aesEncryptEndTime-aesEncryptStartTime)+"ms");        System.out.println("encryptData:"+encryptData);
        // AES алгоритм Расшифровать временную метку начала
        long aesDecryptStartTime = System.currentTimeMillis();
        String decryptData = AESUtil.decrypt(aesKey, encryptData);
        // AES алгоритм Расшифровать временную метку окончания
        long aesDecryptEndTime = System.currentTimeMillis();
        System.out.println("AESалгоритм Расшифроватькропотливый:"+(aesDecryptEndTime-aesDecryptStartTime)+"ms");
        System.out.println("decryptData:"+decryptData);
    }
}

осуществлять main После метода консоль выводит следующие результаты:

Язык кода:javascript
копировать
aesKey:NLrMFzsrl4w+z1eLEjYbtQ==
Затраченное время AESалгоритмшифрования: 5 мс
encryptData:mZTTCFlc6IUci5ryw5WDGQzHZl2DzGqlX7pg3iVDZJJdtkM5QFsKSbaUsRG3lDn74BxskH+nwUzXVK2zng3kxBR6e5C52gsV/XTb4pS85omfa/VNwJ+JEvqakshCfl93
AESалгоритм Расшифроватькропотливый:0ms
decryptData:{"fromCardNum": "622135689832498329", "payAmount": 1000.00, "toCardNum": "623269874369721685"}

можно увидеть AES алгоритмгенерироватьизсекретный ключдлина по сравнению сRSAалгоритмгенерироватьизсекретный ключнамного короче,иRSA алгоритм同样изшифрованиесодержание,шифрование只кропотливый5ms, и Расшифровать更да不足1ms, Эффективность значительно выше, чемRSA алгоритм.

Заключение

В сфере оплаты,Учет требований безопасности и эффективности.,Обычно используется не один тип шифрованияалгоритма.,ида采用多种шифрованиеалгоритмкомбинацияшифрованиеиз方式。RSAшифрованиеалгоритм Хотя безопасно,Но объем расчета очень большой,менее эффективный,Серьезные проблемы с производительностью могут возникнуть в ситуациях с высоким уровнем параллелизма.

AES Зашифрованный ключ key Существует риск быть перехваченным во время передачи по сети, что представляет собой серьезную угрозу безопасности. Итак, обычный подход заключается в использовании RSA Алгоритм сгенерировал открытый ключ для шифрования AES изсекретный ключ,ЗатемиспользоватьRSA алгоритмгенерироватьиззакрытый ключ Приходить Расшифровать经过网络передача инфекции过Приходить经过шифрованиеизAESсекретный ключ, Использовать последний Расшифровать后изAESсекретный ключ Приходить对报文руководитьшифрованиепередача инфекции。这样既保证ПонятноAESсекретный ключ在网络передача инфекции过程中из安全性,也保证Понятно高并发场景下шифрованиеи Расшифроватьиз高效,Безопасность и эффективность сбалансированы.

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose