问题描述
我的开发团队正在对 Angular 中的请求使用非对称加密(AES128 用于有效负载加密和 RSA 用于密钥加密)。
对于密钥生成,他们使用 UUID 版本 4。格式 -f8066eb3-ed31-4d9e-886a-3fc4b3714b47
寻找非对称加密的等效 java 代码,以使用 REST 自动化这些 API。
面临 AES 加密问题,因为使用 UUID uuid = UUID.randomUUID() 生成的密钥无法加密有效负载,它给出了错误 - 非法 base64 字符 2d。
尝试使用以下代码
'''public static void main(String[] args) throws Exception {
String plainText = "{\"id\":\"a0m1U000001uHYqQAM\"}";
// Generate public and private keys using RSA
Map<String,Object> keys = getRSAKeys();
PrivateKey privateKey = (PrivateKey) keys.get("private");
PublicKey publicKey = (PublicKey) keys.get("public");
// First create an AES Key
UUID uuid = UUID.randomUUID();
String secretAESKeyString = uuid.toString();
// Encrypt our data with AES key
String encryptedText = encryptTextUsingAES(plainText,secretAESKeyString);
// Encrypt AES Key with RSA Public Key
String encryptedAESKeyString = encryptAESKey(secretAESKeyString,publicKey);
// First decrypt the AES Key with RSA private key
String decryptedAESKeyString = decryptAESKey(encryptedAESKeyString,privateKey);
// Now decrypt data using the decrypted AES key!
String decryptedText = decryptTextUsingAES(encryptedText,decryptedAESKeyString);
System.out.println("Input: \n" + plainText);
System.out.println("AES Key: \n" + secretAESKeyString);
System.out.println("decrypted: \n" + decryptedText);
}
// Encrypt text using AES key
public static String encryptTextUsingAES(String plainText,String aesKeyString) throws Exception {
byte[] decodedKey = Base64.getDecoder().decode(aesKeyString);
SecretKey originalKey = new SecretKeySpec(decodedKey,decodedKey.length,"AES");
// AES defaults to AES/ECB/PKCS5Padding in Java 7
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.ENCRYPT_MODE,originalKey);
byte[] byteCipherText = aesCipher.doFinal(plainText.getBytes());
return Base64.getEncoder().encodetoString(byteCipherText);
}
// Decrypt text using AES key
public static String decryptTextUsingAES(String encryptedText,String aesKeyString) throws Exception {
byte[] decodedKey = Base64.getDecoder().decode(aesKeyString);
SecretKey originalKey = new SecretKeySpec(decodedKey,"AES");
// AES defaults to AES/ECB/PKCS5Padding in Java 7
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.DECRYPT_MODE,originalKey);
byte[] bytePlainText = aesCipher.doFinal(Base64.getDecoder().decode(encryptedText));
return new String(bytePlainText);
}
// Get RSA keys. Uses key size of 2048.
private static Map<String,Object> getRSAKeys() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
Map<String,Object> keys = new HashMap<String,Object>();
keys.put("private",privateKey);
keys.put("public",publicKey);
return keys;
}
// Decrypt AES Key using RSA private key
private static String decryptAESKey(String encryptedAESKey,PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE,privateKey);
return new String(cipher.doFinal(Base64.getDecoder().decode(encryptedAESKey)));
}
// Encrypt AES Key using RSA public key
private static String encryptAESKey(String plainAESKey,PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
return Base64.getEncoder().encodetoString(cipher.doFinal(plainAESKey.getBytes()));
}
看到以下错误:
线程“main”中的异常 java.lang.IllegalArgumentException: Illegal base64 character 2d
解决方法
字符串 aesKeyString
不是 base64 编码的字符串,因此解码调用失败。
public static String encryptTextUsingAES(String plainText,String aesKeyString) throws Exception {
byte[] decodedKey = Base64.getDecoder().decode(aesKeyString);
我认为对 AES 密钥使用 UUID 没有充分的理由。有几个答案(例如 this one)显示了如何生成随机 AES 密钥。