当前位置: 首页 > 知识库问答 >
问题:

用AES/RSAJava加密和解密数据

洪河
2023-03-14

我正在尝试通过使用本文中描述的步骤来加密/解密一些数据get-a-illegalblock size异常数据必须不超过256字节。我应该怎么做很清楚,但即使我做错了什么。

这是我的课:

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,但我错了<运行了一段时间后,我得到了一些结果:

[ENCRYPT]之前的数据:

[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]

[解密]密钥之前:

[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。我在Java8上运行它。我在一个测试用例中得到了这些结果,在现实世界中,我的应用程序会将加密数据写入文件,所以它必须能够在不知道对称密钥的情况下对其进行解密。

共有2个答案

宁欣怿
2023-03-14

数组的填充方式似乎不是有意的:

    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];
    }
刘嘉木
2023-03-14

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

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

试着用这一行替换这两行:

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

加密也是如此...

 类似资料:
  • 问题内容: 我迅速编写了一个应用程序,我需要AES加密和解密功能,我从另一个.Net解决方案中接收了加密数据,但是我找不到解决办法。 这是我的.net加密: 我需要迅速解密功能。 问题答案: 我找到了解决方案,它是一个很好的库。 跨平台256位AES加密/解密。 此项目包含在所有平台(C#,iOS,Android)上均可使用的256位AES加密的实现。关键目标之一是通过简单的实现使AES在所有平台

  • 我之所以问这个问题,是因为两天来我读了很多关于crypto AES加密的帖子,就在我以为我得到了它的时候,我意识到我根本没有得到它。 这个帖子是最接近我的问题,我有完全相同的问题,但它没有得到回答: CryptoJS AES加密与JAVA AES解密值不匹配 我得到的是已经加密的字符串(我得到的代码只是为了看看他们是怎么做的),所以修改加密方式不是一个选项。这就是为什么所有类似的问题对我来说都不是

  • 问题内容: 我想使用128位AES加密和16字节密钥对密码进行加密和解密。解密值时出现错误。解密时我丢失任何内容吗? 错误信息 最后我基于@QuantumMechanic答案使用以下解决方案 } 问题答案: 如果对于块密码,您将不使用包含填充方案的转换,则需要使明文中的字节数为该密码的块大小的整数倍。 因此,要么将纯文本填充到16字节的倍数(即AES块大小),要么在创建对象时指定填充方案。例如,您

  • 我有这段代码,它基本上对两条纯文本消息进行加密,然后尝试解密,然后打印。问题是第一条消息恢复得很好,但第二条消息是垃圾。我从本教程下载了这段代码,然后将其修改为使用字符串而不是文件,因为我需要它通过套接字发送加密文本。所以其他endpoint不知道明文的长度,有没有办法找到长度,或者我必须以某种方式将明文的长度与密码一起发送? 现在,我认为解密的中断条件有问题。 另外,main()代码在概念上是否

  • 我试图在Android和PHP端使用AES加密/解密数据,并累犯空答案。 首先,我在Android中生成了对称密钥: 在服务器端,我试图解密数据。我可以解密(从RSA)秘密的AES密钥,并得到它的字符串表示。在客户端(Android)和服务器端(PHP)上是一样的。但是如何使用这个字符串AES密钥来解密数据呢?我尝试了这个(PHP): PHP中的结果: 怎么啦?

  • 问题内容: 我正在尝试使用PyCrypto构建两个接受两个参数的函数:消息和密钥,然后对消息进行加密/解密。 我在网络上找到了几个链接可以帮助我,但是每个链接都有缺陷: 在codekoala上的此代码使用了os.urandom,PyCrypto不建议这样做。 此外,我不能保证给函数的键具有预期的确切长度。我该怎么做才能做到这一点? 另外,有几种模式,推荐哪种?我不知道该怎么用:/ 最后,IV到底是