【问题标题】:dart encryption decryption AES exampledart 加密解密 AES 示例
【发布时间】:2017-12-08 10:56:50
【问题描述】:

你好, 我想要一个使用 Dart 进行 AES 加密和解密的示例。我在 Dart 中看到有一个库密码

https://www.dartdocs.org/documentation/cipher/0.3.0/cipher.api/cipher.api-library.html

这可以帮助做到这一点。但是我这里有两个问题:

  • 加密字符串的简单例子,解密得到初始字符串。

  • 我需要它与其他 AES 库一起使用,假设它们都遵循标准。特别是我的前端是 Dart,后端是 C++,我计划为此使用 crypto++。关键在于crypto++,所需的输入是密钥和初始化向量(IV),而在Dart/cipher中,它似乎不需要IV。我想知道输入要求是否不同,它们不能一起工作。

结论,如果有人可以帮助提供一个将 Dart 与任何库(密码/加密)一起使用的示例,该库可以使用 2 个输入 Key 和 IV 加密/解密字符串,那将极大地帮助我。

谢谢大家

【问题讨论】:

  • Dart Cipher 文档是一个 POS,它们基本上不提供任何信息,因此互操作性会很困难。来自文档:“大多数类都是 Bouncy Castle 从 Java 到 Dart 的端口”,因此您必须访问 Bouncy Castle 文档并尝试弄清楚它们如何应用于 Dart。最好的情况:不要使用。

标签: c++ encryption dart aes


【解决方案1】:

我不会提供完整的示例代码,但是如果你想使用 Dart 加密,你应该使用计数器模式 (CTR) 加密,因为这似乎是仅由 Dart 实现的实际 AES 密码模式。

CTR 也称为 SIC 模式,实现可以在here 找到。它有用地使用ParametersWithIV。如果您要使用非随机随机数,则应将其放在 IV 的高位(最左边,从字节索引 0 开始,因为 CTR 模式通常是大端)。

【讨论】:

    【解决方案2】:

    我终于得到了我的加密解密示例工作,所以我回答了我的问题。最简单的方法是使用 Salsa20 算法,然后将所有内容转换为十六进制字符串,然后再序列化并发送。

    • 加密数据
    • 将 IV 编码为十六进制字符串
    • 将加密数据编码为十六进制字符串
    • 全部序列化并通过网络发送
    • 网络的另一端解码十六进制字符串以获取 IV 和加密数据。
    • 然后使用相同的 IV、相同的密钥(隐式设置为相同)来解密数据

    以下是不通过网络发送的加密/解密代码。

    import "dart:typed_data";
    import 'dart:convert';
    import "package:cipher/cipher.dart";
    import "package:cipher/impl/base.dart";
    
    Uint8List StringToUint8List( String s ) {
      var ret = new Uint8List(s.length);
      for( var i=0 ; i<s.length ; i++ ) {
        ret[i] = s.codeUnitAt(i);
      }
      return ret;
    }
    
    /// UTF16 Decoding
    String Uint8ListToString( Uint8List ui ) {
      String s = new String.fromCharCodes(ui);
      return s;
    }
    
    void main() {
        initCipher();
        final testStr = "Hello, i am a very very very very very very very very long string, please encrypte me";
        final ivStr  = "2urPAr4H"; // Need to have size 8
        final keyStr = "QuJuesMhcssE4e8Q4Kt1XCJW3tcpzcEI"; // Need to have size 32
    
        final _ivEncoded = UTF8.encode(ivStr);
        final _keyEncoded = UTF8.encode(keyStr);
        final _key = new KeyParameter(_keyEncoded);
        final params = new ParametersWithIV(_key,_ivEncoded);
    
        var cipher = new StreamCipher( "Salsa20" );
        cipher..reset()..init( true, params );
        var encryptedEncodedData = cipher.process( StringToUint8List(testStr) );
         var encryptedDataStr = Uint8ListToString(encryptedEncodedData);
    
        cipher..reset()..init( false, params );
        var dencryptedEncodedData = cipher.process( StringToUint8List(encryptedDataStr) );
        var dencryptedDataStr = Uint8ListToString(dencryptedEncodedData);
        //expect(testStr, dencryptedDataStr);
    }
    

    【讨论】:

      【解决方案3】:

      对于现在来到这里的任何人,我基于 PointyCastle 编写了一个自定义包,完全用 Dart 编写,可以为您大大简化 AES。

      https://pub.dev/packages/steel_crypt

      它看起来像这样实现:

      var FortunaKey = CryptKey().genFortuna(); //generate 32 byte key with Fortuna //you can also enter your own
      var iv = CryptKey().genDart(16); //generate iv for AES with Dart Random.secure() //you can also enter your own
      var aesEncrypter = AesCrypt(FortunaKey, 'cbc', 'pkcs7'); //generate AES CBC block encrypter with key and PKCS7 padding
      String encrypted = aesEncrypter.encrypt('somedatahere', iv); //encrypt
      String decrypted = aesEncrypter.decrypt(encrypted, iv); //decrypt
      

      这解决了之前可能出现的输入问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-13
        • 1970-01-01
        • 2012-02-24
        • 2016-09-22
        • 2016-09-21
        • 1970-01-01
        • 2015-01-20
        相关资源
        最近更新 更多