输入数据长度必须是 AES CTR 中密码块大小的倍数
Input data length must be a multiple of cipher's block size in AES CTR
我使用 Dart 的加密包加密了一个字符串。我加密的代码如下。
String encrypt(String kelime) {
final key = Key.fromUtf8('H4WtkvK4qyehIe2kjQfH7we1xIHFK67e'); //32 length
final iv = IV.fromUtf8('HgNRbGHbDSz9T0CC');
final encrypter = Encrypter(AES(key, mode: AESMode.cbc));
final encrypted = encrypter.encrypt(kelime, iv: iv);
return encrypted.base64;
}
然后我用同一个包解码加密数据,我得到这个错误输入数据长度必须是密码块大小的倍数。经过一番研究,我了解到加密包在破译 AES 加密算法时遇到了问题。我了解到加密的单词可以用 Pointycastle 包解密。下面的代码
String decryptt(String cipher) {
final key = Key.fromUtf8('H4WtkvK4qyehIe2kjQfH7we1xIHFK67e');
final iv = IV.fromUtf8('HgNRbGHbDSz9T0CC');
final encryptedText = Encrypted.fromUtf8(cipher);
final ctr = pc.CTRStreamCipher(pc.AESFastEngine())
..init(false, pc.ParametersWithIV(pc.KeyParameter(key.bytes), iv.bytes));
Uint8List decrypted = ctr.process(encryptedText.bytes);
print(String.fromCharCodes(decrypted));
return String.fromCharCodes(decrypted);
}
当我解密用 pointycastle 加密的数据时,我得到这样的输出。
có¥ÄÐÒË.å$[~?q{.. 9
我加密的字是
Hello
我使用的飞镖包
使用 AES/CTR 和 encrypt 包解密时,我无法重现问题。
以下带有加密和相关解密的代码在我的机器上运行良好:
final key = enc.Key.fromUtf8('H4WtkvK4qyehIe2kjQfH7we1xIHFK67e'); //32 length
final iv = enc.IV.fromUtf8('HgNRbGHbDSz9T0CC');
// Encryption
String kelime = 'The quick brown fox jumps over the lazy dog';
final encrypter = enc.Encrypter(enc.AES(key, mode: enc.AESMode.ctr, padding: null));
final encrypted = encrypter.encrypt(kelime, iv: iv);
final ciphertext = encrypted.base64;
print(ciphertext);
// Decryption
final decrypter = enc.Encrypter(enc.AES(key, mode: enc.AESMode.ctr, padding: null));
final decrypted = decrypter.decryptBytes(enc.Encrypted.fromBase64(ciphertext), iv: iv);
final decryptedData = utf8.decode(decrypted);
print(decryptedData);
CTR是一种不需要填充的流密码模式。与大多数库不同,encrypt 包不会隐式禁用 CTR 模式的填充,因此这必须 显式 (padding: null
)。否则用其他库(如PointyCastle)解密时,一般不会去掉padding bytes
请注意,在发布的代码中,您使用的是 CBC 模式进行加密,而不是 CTR 模式。可能你加密和解密的模式不匹配。
顺便说一句,静态 IV 通常是不安全的,尤其是对于 CTR(但可以用于测试目的),s。 here.
如果将上述代码中的解密块替换为 PointyCastle:
的解密,则解密也有效
// Decryption
final encryptedText = enc.Encrypted.fromBase64(ciphertext);
final ctr = pc.CTRStreamCipher(pc.AESFastEngine())..init(false, pc.ParametersWithIV(pc.KeyParameter(key.bytes), iv.bytes));
final decrypted = ctr.process(encryptedText.bytes);
final decryptedData = utf8.decode(decrypted);
print(decryptedData);
我使用 Dart 的加密包加密了一个字符串。我加密的代码如下。
String encrypt(String kelime) {
final key = Key.fromUtf8('H4WtkvK4qyehIe2kjQfH7we1xIHFK67e'); //32 length
final iv = IV.fromUtf8('HgNRbGHbDSz9T0CC');
final encrypter = Encrypter(AES(key, mode: AESMode.cbc));
final encrypted = encrypter.encrypt(kelime, iv: iv);
return encrypted.base64;
}
然后我用同一个包解码加密数据,我得到这个错误输入数据长度必须是密码块大小的倍数。经过一番研究,我了解到加密包在破译 AES 加密算法时遇到了问题。我了解到加密的单词可以用 Pointycastle 包解密。下面的代码
String decryptt(String cipher) {
final key = Key.fromUtf8('H4WtkvK4qyehIe2kjQfH7we1xIHFK67e');
final iv = IV.fromUtf8('HgNRbGHbDSz9T0CC');
final encryptedText = Encrypted.fromUtf8(cipher);
final ctr = pc.CTRStreamCipher(pc.AESFastEngine())
..init(false, pc.ParametersWithIV(pc.KeyParameter(key.bytes), iv.bytes));
Uint8List decrypted = ctr.process(encryptedText.bytes);
print(String.fromCharCodes(decrypted));
return String.fromCharCodes(decrypted);
}
当我解密用 pointycastle 加密的数据时,我得到这样的输出。
có¥ÄÐÒË.å$[~?q{.. 9
我加密的字是
Hello
我使用的飞镖包
使用 AES/CTR 和 encrypt 包解密时,我无法重现问题。
以下带有加密和相关解密的代码在我的机器上运行良好:
final key = enc.Key.fromUtf8('H4WtkvK4qyehIe2kjQfH7we1xIHFK67e'); //32 length
final iv = enc.IV.fromUtf8('HgNRbGHbDSz9T0CC');
// Encryption
String kelime = 'The quick brown fox jumps over the lazy dog';
final encrypter = enc.Encrypter(enc.AES(key, mode: enc.AESMode.ctr, padding: null));
final encrypted = encrypter.encrypt(kelime, iv: iv);
final ciphertext = encrypted.base64;
print(ciphertext);
// Decryption
final decrypter = enc.Encrypter(enc.AES(key, mode: enc.AESMode.ctr, padding: null));
final decrypted = decrypter.decryptBytes(enc.Encrypted.fromBase64(ciphertext), iv: iv);
final decryptedData = utf8.decode(decrypted);
print(decryptedData);
CTR是一种不需要填充的流密码模式。与大多数库不同,encrypt 包不会隐式禁用 CTR 模式的填充,因此这必须 显式 (padding: null
)。否则用其他库(如PointyCastle)解密时,一般不会去掉padding bytes
请注意,在发布的代码中,您使用的是 CBC 模式进行加密,而不是 CTR 模式。可能你加密和解密的模式不匹配。
顺便说一句,静态 IV 通常是不安全的,尤其是对于 CTR(但可以用于测试目的),s。 here.
如果将上述代码中的解密块替换为 PointyCastle:
的解密,则解密也有效// Decryption
final encryptedText = enc.Encrypted.fromBase64(ciphertext);
final ctr = pc.CTRStreamCipher(pc.AESFastEngine())..init(false, pc.ParametersWithIV(pc.KeyParameter(key.bytes), iv.bytes));
final decrypted = ctr.process(encryptedText.bytes);
final decryptedData = utf8.decode(decrypted);
print(decryptedData);