使用AES / RSA在Java中加密和解密数据

时间:2019-07-23 09:40:47

标签: java encryption aes rsa

我正在尝试通过使用本文getting-a-illegalblocksizeexception-data-must-not-be-longer-than-256-bytes中描述的步骤来加密/解密某些数据。很清楚我应该怎么做,但是即使我做错了。

这是我的课程:

private SecretKeySpec getSymmetricKey() {
    SecureRandom random = new SecureRandom();
    byte[] keyBytes = new byte[16];
    random.nextBytes(keyBytes);
    return new SecretKeySpec(keyBytes, "AES");
}

private byte[] fixSecret(byte[] s) throws UnsupportedEncodingException {
    int length = 16;
    if ((s.length % length) != 0) {
        int missingLength = length - (s.length % length) ;
        byte[] fixed = new byte[s.length + missingLength];
        for (int i = 0; i < missingLength; i++) {
            fixed[i] = 0;
        }
        for (int i = missingLength; i < s.length; i++) {
            fixed[i] = s[i];
        }
        s = fixed;
    }
    return s;
}

public byte[] encryptData(byte[] dataToEncrypt)
        throws KeyStoreException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
        IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {

    dataToEncrypt = fixSecret(dataToEncrypt);

    // Generate a symmetric key Using random AES algorithm
    SecretKeySpec symkey = getSymmetricKey();

    // Encrypt the data with the symmetric key
    Cipher aescipher = Cipher.getInstance("AES");
    aescipher.init(Cipher.ENCRYPT_MODE, symkey);
    byte[] encryptedData = aescipher.doFinal(dataToEncrypt);

    // Encrypt the symmetric key with RSA
    PublicKey publicKey = jksUserSafe.getCertificate("SafeHouseAheadKP").getPublicKey();

    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    cipher.update(symkey.getEncoded());
    byte[] encryptedSymKey = cipher.doFinal();
    // Use a byte array to join everything
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try {
        baos.write(encryptedSymKey);
        baos.write(encryptedData);
        return baos.toByteArray();
    } catch (IOException ex) {
        return null;
    }
}

public byte[] decryptData(byte[] encryptedData) throws Exception {

    if (this.userPassword == null) {
        throw new Exception("User password can't be empty when trying to decrypt data");
    }

    if (encryptedData != null ? encryptedData.length < 512 : true) {
        return null;
    }

    // read key and data separately
    final int SYMMECTRIC_KEY_LENGTH = 512; // this represents the key size after being encrypted
    byte[] symmectricKeyByes = new byte[SYMMECTRIC_KEY_LENGTH];
    for(int i = 0; i < SYMMECTRIC_KEY_LENGTH; i++) {
        symmectricKeyByes[i] = encryptedData[i];
    }

    byte[] dataToDecrypt = new byte[encryptedData.length - SYMMECTRIC_KEY_LENGTH];
    for(int i = SYMMECTRIC_KEY_LENGTH; i < encryptedData.length; i++) {
        dataToDecrypt[i - SYMMECTRIC_KEY_LENGTH] = encryptedData[i];
    }

    // Decrypte the encrypted symmetric key with RSA
    PrivateKey privateKey = (PrivateKey) jksUserSafe.getKey("SafeHouseAheadKP", userPassword.toCharArray());
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    cipher.update(symmectricKeyByes);
    byte[] decryptedKey = cipher.doFinal();
    SecretKeySpec symkey = new SecretKeySpec(decryptedKey, "AES");

    // Decrypte the data with the symmetric key
    Cipher aescipher = Cipher.getInstance("AES");
    aescipher.init(Cipher.DECRYPT_MODE, symkey);
    aescipher.update(dataToDecrypt);

    return aescipher.doFinal();

}

好吧,我尝试了这种fixLength方法,因为我认为问题是AES使用的填充1,但是我错了。
运行一段时间后,我得到了一些结果:

[加密] 之前的数据:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 108, 101, 115, 32, 101, 110, 99, 
114, 121, 112, 116, 97, 116, 105, 111, 110, 32, 116, 101, 115, 116, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0]

以下数据:

[-32, 56, -39, 24, -124, 67, 97, -36, -21, 30, 36, 108, -56, -55, 23, 94, 113, 
-15, 27, -114, -113, -48, -39, 119, 19, 98, -36, 46, 68, 7, -109, -113, -128, 
-13, 92, -78, 76, 69, -118, -106, -51, -124, -18, -123, 66, -16, -15, 19, 125, 
48, 103, -112, -112, 66, 84, 43, -121, 91, -1, -126, 64, -92, -90, -33]

键之前

[115, -96, -44, 97, -56, 62, 6, -127, -110, -60, 88, 80, -44, -81, 86, -94]

输入后键:

[20, 63, 1, -83, 96, 1, 38, -127, 42, 71, -55, -12, 80, -56, 30, 63, 119, 65, 
60, -115, 45, 100, -108, -119, 55, -75, -32, 50, -51, -60, -107, 103, -22, 100, 
-94, -77, 96, -15, 13, 120, 73, 99, 64, 40, 102, 47, 67, -110, 28, -88, -78, 35,
 -94, -116, 86, -128, 23, 70, 4, -110, -111, -121, 87, -90, -106, -52, 56, -30, 
-23, -44, -33, -24, -12, -71, 116, 21, -121, 108, -118, 31, 71, 119, -70, 10, 
-18, -61, -39, 16, 33, -42, 107, 88, 22, -4, -77, 71, -101, 4, -2, -51, 18, 111,
 29, 112, -15, -29, 10, 107, -80, 126, -57, -40, 110, -86, 64, 11, -29, -61, 53, 
-112, 99, -104, -57, -84, -80, 97, 23, 53, 48, 85, 125, -57, 59, -34, -99, 3, 
-65, 105, -121, 97, -34, 39, -23, -7, -98, 125, 42, -62, -102, 41, -61, 100, 
-41, -120, -102, -121, 83, -115, 45, 122, -102, 81, 72, 85, 81, -102, 33, 87, 
-117, 109, 4, 41, 59, 32, 68, -58, 107, 54, 43, -66, -75, -94, 5, 67, -97, 16, 
46, -50, 62, -93, -81, 68, -77, -82, 21, 108, 107, -4, -74, -121, -88, 53, 120, 
-70, 73, -26, 56, 82, 22, -54, 23, 50, 49, -123, -114, 112, -13, 109, 54, -80, 
-40, -97, 65, -110, -76, 89, 91, 87, -57, 46, -89, -19, -14, 55, 60, 46, -89, 
59, -90, 35, 29, -70, -41, 38, -98, 100, 11, 15, 24, 5, -59, -52, 122, -116, 
-72, -121, -93, 122, 59, -64, 42, 33, -13, 43, -51, 18, 47, 60, -46, -90, 105, 
27, -89, -113, 2, 1, -75, -15, 37, -68, 24, -80, 85, 74, 7, 34, 80, 45, -63, 
-125, -16, 38, 29, -11, 81, -82, -15, -30, 66, -108, 73, 34, -87, -30, 11, 42, 
-122, 41, -37, -34, 111, -119, 34, 116, -116, 95, -99, -69, -71, 67, -61, -106,
 -76, -47, -81, -21, -54, -105, -84, -6, -61, 118, -9, 126, 93, 70, 101, 22, 91,
 14, 18, -108, 52, 115, 53, -104, -100, -34, -85, 48, -62, 92, -19, 93, -64, 41,
 -100, -76, 103, -108, 94, 65, 82, -41, 73, 73, 80, 51, 12, 94, 93, -109, 24, 
36, -12, 19, 29, -106, -71, 23, 108, 17, -107, 37, -4, 8, 107, -39, 37, 42, -26,
 65, -24, 20, -18, 33, 35, 65, 12, 23, -70, 22, 14, 61, 61, 126, 102, -90, 64, 
-57, 72, 90, 23, -15, 89, -47, -26, 29, 81, -93, 4, -79, 74, 7, 19, -37, 43, 
-87, 19, -17, 91, 90, -79, -64, -78, -86, -50, -70, -12, -120, 31, 73, -106, 
-17, 5, -48, 23, -28, 75, 23, -75, -27, -75, 122, -52, 8, -87, 37, -22, -54, 
-72, -45, -44, -15, 5, -85, -26, 13, 30, 74, 93, 121, -33, 79, 96, -63, 16, -5, 
19, 47, 20, -8, -104, 31, 24, -19, -110, -88, 124, 127, 0, -86, 75, -46, 119, 
-69, 114, 115, -80, -38, -51, -12, -128, -34, -14, 30, -83, 1, 45, -37, -66, 75]

[DECRYPT] 之前的密钥:

[20, 63, 1, -83, 96, 1, 38, -127, 42, 71, -55, -12, 80, -56, 30, 63, 119, 65, 
60, -115, 45, 100, -108, -119, 55, -75, -32, 50, -51, -60, -107, 103, -22, 100, 
-94, -77, 96, -15, 13, 120, 73, 99, 64, 40, 102, 47, 67, -110, 28, -88, -78, 35, 
-94, -116, 86, -128, 23, 70, 4, -110, -111, -121, 87, -90, -106, -52, 56, -30, 
-23, -44, -33, -24, -12, -71, 116, 21, -121, 108, -118, 31, 71, 119, -70, 10, 
-18, -61, -39, 16, 33, -42, 107, 88, 22, -4, -77, 71, -101, 4, -2, -51, 18, 111, 
29, 112, -15, -29, 10, 107, -80, 126, -57, -40, 110, -86, 64, 11, -29, -61, 53, 
-112, 99, -104, -57, -84, -80, 97, 23, 53, 48, 85, 125, -57, 59, -34, -99, 3, 
-65, 105, -121, 97, -34, 39, -23, -7, -98, 125, 42, -62, -102, 41, -61, 100, 
-41, -120, -102, -121, 83, -115, 45, 122, -102, 81, 72, 85, 81, -102, 33, 87, 
-117, 109, 4, 41, 59, 32, 68, -58, 107, 54, 43, -66, -75, -94, 5, 67, -97, 16, 
46, -50, 62, -93, -81, 68, -77, -82, 21, 108, 107, -4, -74, -121, -88, 53, 120, 
-70, 73, -26, 56, 82, 22, -54, 23, 50, 49, -123, -114, 112, -13, 109, 54, -80,
 -40, -97, 65, -110, -76, 89, 91, 87, -57, 46, -89, -19, -14, 55, 60, 46, -89, 
59, -90, 35, 29, -70, -41, 38, -98, 100, 11, 15, 24, 5, -59, -52, 122, -116, 
-72, -121, -93, 122, 59, -64, 42, 33, -13, 43, -51, 18, 47, 60, -46, -90, 105, 
27, -89, -113, 2, 1, -75, -15, 37, -68, 24, -80, 85, 74, 7, 34, 80, 45, -63, 
-125, -16, 38, 29, -11, 81, -82, -15, -30, 66, -108, 73, 34, -87, -30, 11, 42, 
-122, 41, -37, -34, 111, -119, 34, 116, -116, 95, -99, -69, -71, 67, -61, -106, 
-76, -47, -81, -21, -54, -105, -84, -6, -61, 118, -9, 126, 93, 70, 101, 22, 91, 
14, 18, -108, 52, 115, 53, -104, -100, -34, -85, 48, -62, 92, -19, 93, -64, 41, 
-100, -76, 103, -108, 94, 65, 82, -41, 73, 73, 80, 51, 12, 94, 93, -109, 24, 36, 
-12, 19, 29, -106, -71, 23, 108, 17, -107, 37, -4, 8, 107, -39, 37, 42, -26, 65,
 -24, 20, -18, 33, 35, 65, 12, 23, -70, 22, 14, 61, 61, 126, 102, -90, 64, -57, 
72, 90, 23, -15, 89, -47, -26, 29, 81, -93, 4, -79, 74, 7, 19, -37, 43, -87, 19, 
-17, 91, 90, -79, -64, -78, -86, -50, -70, -12, -120, 31, 73, -106, -17, 5, -48, 
23, -28, 75, 23, -75, -27, -75, 122, -52, 8, -87, 37, -22, -54, -72, -45, -44, 
-15, 5, -85, -26, 13, 30, 74, 93, 121, -33, 79, 96, -63, 16, -5, 19, 47, 20, -8, 
-104, 31, 24, -19, -110, -88, 124, 127, 0, -86, 75, -46, 119, -69, 114, 115, 
-80, -38, -51, -12, -128, -34, -14, 30, -83, 1, 45, -37, -66, 75]

输入后键:

[115, -96, -44, 97, -56, 62, 6, -127, -110, -60, 88, 80, -44, -81, 86, -94]

之前的数据:

[-32, 56, -39, 24, -124, 67, 97, -36, -21, 30, 36, 108, -56, -55, 23, 94, 113, 
-15, 27, -114, -113, -48, -39, 119, 19, 98, -36, 46, 68, 7, -109, -113, -128, 
-13, 92, -78, 76, 69, -118, -106, -51, -124, -18, -123, 66, -16, -15, 19, 125, 
48, 103, -112, -112, 66, 84, 43, -121, 91, -1, -126, 64, -92, -90, -33]

以下数据: []

为什么AES无法解密它?

更多有用的信息:

我的非对称密钥是4096。我在Java 8上运行它。我在一个测试用例中得到了这些结果,在现实世界中,我的应用程序会将加密的数据写入文件,因此它必须能够解密而不知道对称密钥。

2 个答案:

答案 0 :(得分:2)

您正在丢弃cipher.update()中的数据。.在下面的两个语句中,update(...)doFinal()都可以返回解密的数据..

cipher.update(symmectricKeyByes);
byte[] decryptedKey = cipher.doFinal();

尝试仅用这一行替换两行:

byte[] decryptedKey = cipher.doFinal(symmectricKeyByes);

加密也一样..

答案 1 :(得分:1)

似乎不想要的是如何填充数组:

    byte[] fixed = new byte[s.length + missingLength];
    // Automatically zeroed.
    //for (int i = 0; i < missingLength; i++) {
    //    fixed[i] = 0;
    //}
    for (int i = missingLength; i < fixed.length; i++) {
        fixed[i] = s[i - missingLength];
    }