flutter - 输入数据长度必须是 AES CTR 中密码 block 大小的倍数

标签 flutter dart aes pointycastle

我使用 Dart 的 encrypt 包加密一个字符串。我加密的代码如下。

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;
  }
然后我用同一个包解码加密数据,我得到这个错误输入数据长度必须是密码块大小的倍数。经过一番研究,我了解到 encrypt 包在破译 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


我用的 Dart 包
  • https://pub.dev/packages/pointycastle
  • https://pub.dev/packages/encrypt
  • 最佳答案

    使用 AES/CTR 和加密包解密时,我无法重现该问题。
    以下带有加密和关联解密的代码在我的机器上运行良好:

    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)解密时,填充字节一般不会被去除。
    请注意,在发布的代码中,您使用的是 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);
    

    关于flutter - 输入数据长度必须是 AES CTR 中密码 block 大小的倍数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67244624/

    相关文章:

    flutter - 如何在Streambuilder中控制流(启动,暂停,恢复)

    flutter - 如何在 Flutter 中创建带条纹的背景

    database - 如何在 flutter 朔迷离的Firestore卡片列表中显示我的结果

    flutter - 将ListView嵌套到DropdownMenu中

    c# - 加密字符串从Delphi到C#

    java加密大文件导致java.lang.OutOfMemoryError : Java heap space,可能的解决方案

    dart - 如何创建带有 2 个 Widget 的 Listtile?

    firebase - 如何在flutter中的Firebase身份验证中验证电子邮件?

    inheritance - Dart 继承和 super 构造函数

    objective-c - iOS 13 中的 AES 加密 CryptLib 不起作用