js java aes_CryptoJS AES加密和Java AES解密

小编典典

免责声明:除非您了解加密概念,包括链接模式,密钥派生功能,IV和块大小,否则不要使用加密。

而且,不要推出自己的安全方案,而要遵循既定的方案。仅仅使用加密算法并不意味着应用程序变得更加安全。

CryptoJS实现与OpenSSL相同的密钥派生功能,并采用相同的格式将IV放入加密的数据中。因此,适用于处理OpenSSL编码数据的所有Java代码。

给出以下Javascript代码:

var text = "The quick brown fox jumps over the lazy dog. 👻 👻";

var secret = "René Über";

var encrypted = CryptoJS.AES.encrypt(text, secret);

encrypted = encrypted.toString();

console.log("Cipher text: " + encrypted);

我们得到密文:

U2FsdGVkX1+tsmZvCEFa/iGeSA0K7gvgs9KXeZKwbCDNCs2zPo+BXjvKYLrJutMK+hxTwl/hyaQLOaD7LLIRo2I5fyeRMPnroo6k8N9uwKk=

在Java方面,

String secret = "René Über";

String cipherText = "U2FsdGVkX1+tsmZvCEFa/iGeSA0K7gvgs9KXeZKwbCDNCs2zPo+BXjvKYLrJutMK+hxTwl/hyaQLOaD7LLIRo2I5fyeRMPnroo6k8N9uwKk=";

byte[] cipherData = Base64.getDecoder().decode(cipherText);

byte[] saltData = Arrays.copyOfRange(cipherData, 8, 16);

MessageDigest md5 = MessageDigest.getInstance("MD5");

final byte[][] keyAndIV = GenerateKeyAndIV(32, 16, 1, saltData, secret.getBytes(StandardCharsets.UTF_8), md5);

SecretKeySpec key = new SecretKeySpec(keyAndIV[0], "AES");

IvParameterSpec iv = new IvParameterSpec(keyAndIV[1]);

byte[] encrypted = Arrays.copyOfRange(cipherData, 16, cipherData.length);

Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding");

aesCBC.init(Cipher.DECRYPT_MODE, key, iv);

byte[] decryptedData = aesCBC.doFinal(encrypted);

String decryptedText = new String(decryptedData, StandardCharsets.UTF_8);

System.out.println(decryptedText);

结果是:

The quick brown fox jumps over the lazy dog. 👻 👻

这就是我们开始的内容。表情符号,口音和变音符号也可以使用。

/**

* Generates a key and an initialization vector (IV) with the given salt and password.

*

* This method is equivalent to OpenSSL's EVP_BytesToKey function

* (see https://github.com/openssl/openssl/blob/master/crypto/evp/evp_key.c).

* By default, OpenSSL uses a single iteration, MD5 as the algorithm and UTF-8 encoded password data.

*

* @param keyLength the length of the generated key (in bytes)

* @param ivLength the length of the generated IV (in bytes)

* @param iterations the number of digestion rounds

* @param salt the salt data (8 bytes of data or null)

* @param password the password data (optional)

* @param md the message digest algorithm to use

* @return an two-element array with the generated key and IV

*/

public static byte[][] GenerateKeyAndIV(int keyLength, int ivLength, int iterations, byte[] salt, byte[] password, MessageDigest md) {

int digestLength = md.getDigestLength();

int requiredLength = (keyLength + ivLength + digestLength - 1) / digestLength * digestLength;

byte[] generatedData = new byte[requiredLength];

int generatedLength = 0;

try {

md.reset();

// Repeat process until sufficient data has been generated

while (generatedLength < keyLength + ivLength) {

// Digest data (last digest if available, password data, salt if available)

if (generatedLength > 0)

md.update(generatedData, generatedLength - digestLength, digestLength);

md.update(password);

if (salt != null)

md.update(salt, 0, 8);

md.digest(generatedData, generatedLength, digestLength);

// additional rounds

for (int i = 1; i < iterations; i++) {

md.update(generatedData, generatedLength, digestLength);

md.digest(generatedData, generatedLength, digestLength);

}

generatedLength += digestLength;

}

// Copy key and IV into separate byte arrays

byte[][] result = new byte[2][];

result[0] = Arrays.copyOfRange(generatedData, 0, keyLength);

if (ivLength > 0)

result[1] = Arrays.copyOfRange(generatedData, keyLength, keyLength + ivLength);

return result;

} catch (DigestException e) {

throw new RuntimeException(e);

} finally {

// Clean out temporary data

Arrays.fill(generatedData, (byte)0);

}

}

请注意,您必须安装Java密码学扩展(JCE)无限强度管辖权策略。否则,密钥大小为256的AES将无法工作并引发异常:

java.security.InvalidKeyException: Illegal key size

更新资料

我已经取代奥拉·比尼的Java代码的EVP_BytesToKey,我在我的答案的第一个版本,搭配出更地道,更容易理解Java代码(见上文)。

2020-09-11

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值