Как платежное учреждение, большая часть передаваемых данных является очень конфиденциальной, например, идентификационный номер, номер банковской карты, пароль банковской карты и т. д. Как только эта информация будет перехвачена преступниками, банковские карты могут быть напрямую украдены, что приведет к огромным потерям для потребителей. Если информация, полученная преступниками, зашифрована и нет ключа для дешифрования, то для преступников эта информация — просто тарабарщина. В этом и заключается самый важный смысл шифрования.
В настоящее время наиболее используемое шифрование、Расшифроватьалгоритм Есть две основные категории:Симметричный алгоритм шифрованияиНет Симметричный алгоритм шифрования。Основное различие между ними заключается вшифрованиеи Расшифроватьизсекретный ключ Это соответствует?,последовательныйто естьсимметрияшифрование,不последовательныйто есть Нетсимметрияшифрование。симметрияшифрование常用издаAES
шифрованиеалгоритм,Нет Симметричный алгоритм шифрования常用издаRSA
шифрованиеалгоритм,Представлено ниже RSA
шифрованиеалгоритмиAES
шифрованиеалгоритм在支付项目中из应用。
RSA
Это алгоритм асимметричного шифрования, который позволяет завершить расшифровку без передачи секретного ключа, избегая возможности взлома из-за прямой передачи секретного ключа при симметричном шифровании. риск。RSA
Шифрование/дешифрованиепо паре пооткрытый ключизакрытый ключ组成изсекретный ключ Завершено вместешифрованиеи Расшифровать,открытый ключ общедоступен, используется для шифрования, скрытности ключда保密из,используется для Расшифровать。两者之间通过一定изалгоритмассоциация,Основная идея состоит в том, чтобы использовать сложность факторизации пары чрезвычайно больших целых чисел для обеспечения безопасности.
Предположим, что A — платежное учреждение.,B — торговец платежного учреждения,Первый乙之间需要руководитьданныеизпередача инфекции。Если вы хотитеданныеруководитьШифрование/дешифрование,тогда ты должен сначалагенерироватьключ:Первыйгенерироватьпарасекретный ключ(открытый ключизакрытый ключ),открытый ключ Отдать Б,закрытый ключ оставляет себе аналогично, B также порождает пару закрытых самцов; ключ,открытый ключ给Первый,закрытый ключ Держи это при себе. Конкретный процесс показан на рисунке ниже:
Понятносекретный ключ Тогда ты сможешь对передача инфекцииизданныеруководитьшифрование Понятно。данныепередача инфекциида双向из,Следовательно, шифрование/дешифрование в платежной индустрии также является двусторонним.,Конкретные шаги заключаются в следующем:
1) B использует открытый ключ A для шифрования передаваемых данных и отправляет зашифрованные данные A;
2) А получает зашифрованные данные от Б и расшифровывает их с помощью своего закрытого ключа;
3) А шифрует обработанные данные с помощью открытого ключа Б и возвращает их Б;
4) B принимает возвращенные данные и расшифровывает их с помощью своего закрытого ключа.
Вышеуказанные шаги представляют собой относительно стандартный процесс шифрования/дешифрования для платежного учреждения.,Первый乙双方分别использовать对方изоткрытый ключ шифрования, затем используйте свой собственный закрытый ключ Расшифровать,Конкретный процесс показан на рисунке ниже:
JDK
Уже упаковано RSA
Шифрование/дешифрованиеизметод,Если вы хотитеданные Шифрование/дешифрование,тогда тебе нужно сначалагенерироватьпарасекретный ключ。генерироватьключиз代码Как показано ниже:
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;
}
}
генерироватьоткрытый ключизакрытый ключ Тогда ты сможешьшифрование Расшифровать Понятно,Пример Шифования/дешифрования выглядит так:
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));
}
}
тогда напишитестзавершение занятийгенерироватьмужскойзакрытый ключи сделать банковский переводданныеруководитьшифрованиеи Расшифроватьизтестметод,Как показано ниже:
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.
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
из优点在于效率Нет常高,по сравнению сRSA
алгоритмиз效率要高得多。AES
алгоритм Процесс шифрования/дешифрования показан ниже:
AES
Для шифрования и дешифрования требуется секретный ключ. Секретный ключ генерируется заранее. После того, как платежное учреждение сгенерирует ключ в соответствии с определенными правилами, он передается продавцу. Данные, предоставленные продавцом, необходимо зашифровать с помощью. секретный ключ. После того, как платежное учреждение получит зашифрованный текст. Используйте тот же секретный ключ для расшифровки.
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. Код класса следующий:
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
После метода консоль выводит следующие результаты:
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
секретный ключ在网络передача инфекции过程中из安全性,也保证Понятно高并发场景下шифрованиеи Расшифроватьиз高效,Безопасность и эффективность сбалансированы.