您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

AES-Java中的简单加密,使用openssl解密

AES-Java中的简单加密,使用openssl解密

问题确实是由于OpenSSL从密码计算出的密钥所致。

原因很可能是OpenSSL拥有自己的算法来从密码派生密钥EVP_BytesToKey,这与Java的算法不同。

我发现的唯一解决方案是使用该算法的Java重新实现:

private static final int KEY_LENGTH = 32;    

private byte[] deriveKey(String encryptionPassword, byte[] salt) throws NoSuchAlgorithmException {
    final byte[] passAndSalt = ArrayUtils.addAll(encryptionPassword.getBytes(), salt);
    byte[] hash = new byte[0];
    byte[] keyAndIv = new byte[0];
    for (int i = 0; i < 3 && keyAndIv.length < KEY_LENGTH; i++) {
        final byte[] dataToHash = ArrayUtils.addAll(hash, passAndSalt);
        final MessageDigest md = MessageDigest.getInstance("SHA-256");
        hash = md.digest(dataToHash);
        keyAndIv = ArrayUtils.addAll(keyAndIv, hash);
    }
    return Arrays.copyOfRange(keyAndIv, 0, KEY_LENGTH);
}
ArrayUtils 是Apache Commons库的一部分。

完整用法:

IvParameterSpec initializationVectorSpec = new IvParameterSpec(
                Hex.decodeHex(encryptionInitializationVector.tocharArray()));

cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] salt = new SecureRandom().generateSeed(8);
byte[] key = deriveKey(encryptionPassword, salt);
Key keySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, initializationVectorSpec);

byte[] rawEncryptedInput = cipher.doFinal(input.getBytes());
byte[] encryptedInputWithPrependedSalt = ArrayUtils.addAll(ArrayUtils.addAll(
                "Salted__".getBytes(), salt), rawEncryptedInput);
return Base64.getEncoder()
                .encodeToString(encryptedInputWithPrependedSalt);
java 2022/1/1 18:17:46 有500人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶