面临 AES 加密问题,因为使用 UUID 生成的密钥无法加密有效负载

问题描述

我的开发团队正在对 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 密钥。