是否存在与 CryptoJS 中 Jasypt-Library 的 AES256TextEncryptor Class 等效的行为?
Is there a behavioral equivalent to the AES256TextEncryptor Class of the Jasypt-Library in CryptoJS?
作为密码学的新手,我正在尝试使用 CrpytoJS 库重现与 jasypt 库的 AES256TextEncryptor Class 相同的默认行为。这是我的 Java 方法,它基本上接受两个参数 - 我要加密的消息以及我的秘密释义:
private String encryptWithAes256(String messageToBeEncrypted, String encryptorSecret) {
AES256TextEncryptor encryptor = new AES256TextEncryptor();
encryptor.setPassword(encryptorSecret);
return encryptor.encrypt(messageToBeEncrypted);
}
当使用此代码加密 messageToBeEncrypted 时,生成的加密消息没有问题。我发现内部使用 StandardPBEStringEncryptor 作为加密器的 AES256TextEncryptor 似乎默认使用 PBEWithHMACSHA512AndAES_256 算法。
如何使用 CrpytoJS 重现相同的加密行为?当我尝试按照记录的方式使用 CryptoJS 加密消息时 here,结果与我预期的完全不同。
基于 Topaco 的 ,我想出了以下 Java 脚本代码来模仿 Java 代码:
function encryptWithAes256(messageToEncrypt, encryptorKey){
// Generate random 16 bytes salt
var salt = CryptoJS.lib.WordArray.random(128/8);
// Derive key
var key = CryptoJS.PBKDF2(encryptorKey, salt, { keySize: 256/32, iterations: 1000 });
console.log("derived key: " + key);
// Generate random 16 bytes init vector (iv)
var iv = CryptoJS.lib.WordArray.random(128/8);
var cipherText = CryptoJS.AES.encrypt(messageToEncrypt, key, {iv: iv});
console.log("aes encrypted text: "+ salt.toString() + iv.toString() + cipherText.toString());
}
生成的结果似乎仍然不是预期的那样,因为它的长度是 88 个字符,而 Java 代码生成了 64 个字符长的加密消息。
发布的代码接近要求的结果。以下还有待更正:
- PBKDF2默认使用SHA1,这意味着必须明确指定SHA512。
- 必须在二进制级别进行串联,而不是使用十六进制和 Base64 编码数据。
如果这是固定的,可能的实现是:
function encryptWithAes256(messageToEncrypt, encryptorKey){
// Generate random 16 bytes salt
var salt = CryptoJS.lib.WordArray.random(128/8);
// Derive key
var key = CryptoJS.PBKDF2(
encryptorKey,
salt,
{ keySize: 256/32, iterations: 1000, hasher: CryptoJS.algo.SHA512 } // Apply SHA512
);
console.log("derived key:\n" + key);
// Generate random 16 bytes init vector (iv)
var iv = CryptoJS.lib.WordArray.random(128/8);
// Encrypt
var cipherText = CryptoJS.AES.encrypt(messageToEncrypt, key, {iv: iv});
// Concatenate
var encryptedData = salt.clone().concat(iv).concat(cipherText.ciphertext); // Concatenate on binary level
var encryptedDataB64 = encryptedData.toString(CryptoJS.enc.Base64); // Base64 encode the result
console.log("aes encrypted text:\n", encryptedDataB64.replace(/(.{56})/g,'\n'));
}
encryptWithAes256('The quick brown fox jumps over the lazy dog', 'my passphrase');
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
由于随机盐和 IV 总是生成不同的数据,因此无法通过比较数据来测试实现。相反,必须检查用 CryptoJS 代码生成的数据是否可以用 Jasypt 对应解密:
private static String decryptWithAes256(String ciphertextToBeDecrypted, String encryptorSecret) {
AES256TextEncryptor encryptor = new AES256TextEncryptor();
encryptor.setPassword(encryptorSecret);
return encryptor.decrypt(ciphertextToBeDecrypted);
}
上面的 CryptoJS 实现确实是这种情况。
作为密码学的新手,我正在尝试使用 CrpytoJS 库重现与 jasypt 库的 AES256TextEncryptor Class 相同的默认行为。这是我的 Java 方法,它基本上接受两个参数 - 我要加密的消息以及我的秘密释义:
private String encryptWithAes256(String messageToBeEncrypted, String encryptorSecret) {
AES256TextEncryptor encryptor = new AES256TextEncryptor();
encryptor.setPassword(encryptorSecret);
return encryptor.encrypt(messageToBeEncrypted);
}
当使用此代码加密 messageToBeEncrypted 时,生成的加密消息没有问题。我发现内部使用 StandardPBEStringEncryptor 作为加密器的 AES256TextEncryptor 似乎默认使用 PBEWithHMACSHA512AndAES_256 算法。
如何使用 CrpytoJS 重现相同的加密行为?当我尝试按照记录的方式使用 CryptoJS 加密消息时 here,结果与我预期的完全不同。
基于 Topaco 的
function encryptWithAes256(messageToEncrypt, encryptorKey){
// Generate random 16 bytes salt
var salt = CryptoJS.lib.WordArray.random(128/8);
// Derive key
var key = CryptoJS.PBKDF2(encryptorKey, salt, { keySize: 256/32, iterations: 1000 });
console.log("derived key: " + key);
// Generate random 16 bytes init vector (iv)
var iv = CryptoJS.lib.WordArray.random(128/8);
var cipherText = CryptoJS.AES.encrypt(messageToEncrypt, key, {iv: iv});
console.log("aes encrypted text: "+ salt.toString() + iv.toString() + cipherText.toString());
}
生成的结果似乎仍然不是预期的那样,因为它的长度是 88 个字符,而 Java 代码生成了 64 个字符长的加密消息。
发布的代码接近要求的结果。以下还有待更正:
- PBKDF2默认使用SHA1,这意味着必须明确指定SHA512。
- 必须在二进制级别进行串联,而不是使用十六进制和 Base64 编码数据。
如果这是固定的,可能的实现是:
function encryptWithAes256(messageToEncrypt, encryptorKey){
// Generate random 16 bytes salt
var salt = CryptoJS.lib.WordArray.random(128/8);
// Derive key
var key = CryptoJS.PBKDF2(
encryptorKey,
salt,
{ keySize: 256/32, iterations: 1000, hasher: CryptoJS.algo.SHA512 } // Apply SHA512
);
console.log("derived key:\n" + key);
// Generate random 16 bytes init vector (iv)
var iv = CryptoJS.lib.WordArray.random(128/8);
// Encrypt
var cipherText = CryptoJS.AES.encrypt(messageToEncrypt, key, {iv: iv});
// Concatenate
var encryptedData = salt.clone().concat(iv).concat(cipherText.ciphertext); // Concatenate on binary level
var encryptedDataB64 = encryptedData.toString(CryptoJS.enc.Base64); // Base64 encode the result
console.log("aes encrypted text:\n", encryptedDataB64.replace(/(.{56})/g,'\n'));
}
encryptWithAes256('The quick brown fox jumps over the lazy dog', 'my passphrase');
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
由于随机盐和 IV 总是生成不同的数据,因此无法通过比较数据来测试实现。相反,必须检查用 CryptoJS 代码生成的数据是否可以用 Jasypt 对应解密:
private static String decryptWithAes256(String ciphertextToBeDecrypted, String encryptorSecret) {
AES256TextEncryptor encryptor = new AES256TextEncryptor();
encryptor.setPassword(encryptorSecret);
return encryptor.decrypt(ciphertextToBeDecrypted);
}
上面的 CryptoJS 实现确实是这种情况。