使用 flutter/dart 加密并使用 CryptoJS returns 空字符串解密 aes
Encrypt with flutter/dart and decrypt aes with CryptoJS returns empty string
我已经使用 dart 库在 flutter 中加密 encrypt。下面是代码示例:
import 'package:encrypt/encrypt.dart' as enc;
final key = enc.Key.fromUtf8('Thisisasamplekeythatamusinginmyc'); //32 chars
final iv = enc.IV.fromUtf8('thisismysampleiv');//16 chars
String encryptMyData(String text) {
final e = enc.Encrypter(enc.AES(key));
final encrypted_data = e.encrypt(text, iv: iv);
return encrypted_data.base64;
}
我能够加密,但是当我尝试使用 JavaScript 中的此代码解密代码时出现问题,使用 Crypto-JS:
const cryptkey = CryptoJS.enc.Utf8.parse('Thisisasamplekeythatamusinginmyc');
const crypted = CryptoJS.enc.Base64.parse("fdsUYHdv/5PoJSoZGwWppw==");
var decrypt = CryptoJS.AES.decrypt({ciphertext: crypted}, cryptkey, {
iv: CryptoJS.enc.Hex.parse('thisismysampleiv'),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log(decrypt.toString(CryptoJS.enc.Utf8));
问题是它总是 returns 一个空字符串,即使使用 AES.js 库也是如此。
我查看了 ,但存在同样的问题。
CryptoJS 代码不兼容,因为 IV 解码不正确。必须使用 Utf8 编码器而不是 Hex 编码器。
此外,encrypt 库默认应用 CTR 模式。因此,在CryptoJS代码中必须使用CTR模式,而不是CBC模式:
const cryptkey = CryptoJS.enc.Utf8.parse('Thisisasamplekeythatamusinginmyc');
const cryptiv = CryptoJS.enc.Utf8.parse('thisismysampleiv')
// Decryption
const crypted = CryptoJS.enc.Base64.parse("fdsUYHdv/5PoJSoZGwWppw==");
var decrypt = CryptoJS.AES.decrypt({ciphertext: crypted}, cryptkey, {
iv: cryptiv,
mode: CryptoJS.mode.CTR
});
console.log(decrypt.toString(CryptoJS.enc.Utf8));
// Encryption
var encrypt = CryptoJS.AES.encrypt("Sample Text", cryptkey, {
iv: cryptiv,
mode: CryptoJS.mode.CTR
});
console.log(encrypt.toString())
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
对于像 CTR 这样的流密码模式,通常不使用填充。请注意,这两个库都默认应用 PKCS#7 填充,并且不会为流密码模式自动禁用它。因此,填充应该显式在两侧禁用(Dart端为padding: null
,CryptoJS端为padding: CryptoJS.pad.NoPadding
)。
或者,可以在两侧使用像 CBC 这样的分组密码模式。然后,必须应用填充 (例如 PKCS#7)。
如果在测试之外使用静态 IV 和密钥密码:那么,出于安全原因,应该应用密钥派生函数,例如 PBKDF2。此外,对于每次加密,应生成随机 IV,将其与密文(通常串联)一起传递给另一方。
我已经使用 dart 库在 flutter 中加密 encrypt。下面是代码示例:
import 'package:encrypt/encrypt.dart' as enc;
final key = enc.Key.fromUtf8('Thisisasamplekeythatamusinginmyc'); //32 chars
final iv = enc.IV.fromUtf8('thisismysampleiv');//16 chars
String encryptMyData(String text) {
final e = enc.Encrypter(enc.AES(key));
final encrypted_data = e.encrypt(text, iv: iv);
return encrypted_data.base64;
}
我能够加密,但是当我尝试使用 JavaScript 中的此代码解密代码时出现问题,使用 Crypto-JS:
const cryptkey = CryptoJS.enc.Utf8.parse('Thisisasamplekeythatamusinginmyc');
const crypted = CryptoJS.enc.Base64.parse("fdsUYHdv/5PoJSoZGwWppw==");
var decrypt = CryptoJS.AES.decrypt({ciphertext: crypted}, cryptkey, {
iv: CryptoJS.enc.Hex.parse('thisismysampleiv'),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log(decrypt.toString(CryptoJS.enc.Utf8));
问题是它总是 returns 一个空字符串,即使使用 AES.js 库也是如此。
我查看了
CryptoJS 代码不兼容,因为 IV 解码不正确。必须使用 Utf8 编码器而不是 Hex 编码器。
此外,encrypt 库默认应用 CTR 模式。因此,在CryptoJS代码中必须使用CTR模式,而不是CBC模式:
const cryptkey = CryptoJS.enc.Utf8.parse('Thisisasamplekeythatamusinginmyc');
const cryptiv = CryptoJS.enc.Utf8.parse('thisismysampleiv')
// Decryption
const crypted = CryptoJS.enc.Base64.parse("fdsUYHdv/5PoJSoZGwWppw==");
var decrypt = CryptoJS.AES.decrypt({ciphertext: crypted}, cryptkey, {
iv: cryptiv,
mode: CryptoJS.mode.CTR
});
console.log(decrypt.toString(CryptoJS.enc.Utf8));
// Encryption
var encrypt = CryptoJS.AES.encrypt("Sample Text", cryptkey, {
iv: cryptiv,
mode: CryptoJS.mode.CTR
});
console.log(encrypt.toString())
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
对于像 CTR 这样的流密码模式,通常不使用填充。请注意,这两个库都默认应用 PKCS#7 填充,并且不会为流密码模式自动禁用它。因此,填充应该显式在两侧禁用(Dart端为padding: null
,CryptoJS端为padding: CryptoJS.pad.NoPadding
)。
或者,可以在两侧使用像 CBC 这样的分组密码模式。然后,必须应用填充 (例如 PKCS#7)。
如果在测试之外使用静态 IV 和密钥密码:那么,出于安全原因,应该应用密钥派生函数,例如 PBKDF2。此外,对于每次加密,应生成随机 IV,将其与密文(通常串联)一起传递给另一方。