美文网首页Flutter
Flutter RSA加密、解密之我见一

Flutter RSA加密、解密之我见一

作者: 小王在努力 | 来源:发表于2020-05-25 18:25 被阅读0次

    1、需要公钥和私钥

    公钥内容:
    -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+XpiP5bcOmzgOHG0eRDVx41kP
    ECiMCx14KduElU53kCyY02xETFC/KxF8mpFCEM9b8iTSAKjRbAs8CXQtSJIxv9d9
    /a6OhXKg6WadljRmVoZZm9MD2MGixMGYN2W3noEkfUHeWUtghk8ohcAMdl4mwanm
    +JBAkTEOsVlegk/27QIDAQAB
    -----END PUBLIC KEY-----
    
    私钥内容:
    -----BEGIN PRIVATE KEY-----
    MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL5emI/ltw6bOA4c
    bR5ENXHjWQ8QKIwLHXgp24SVTneQLJjTbERMUL8rEXyakUIQz1vyJNIAqNFsCzwJ
    dC1IkjG/1339ro6FcqDpZp2WNGZWhlmb0wPYwaLEwZg3ZbeegSR9Qd5ZS2CGTyiF
    wAx2XibBqeb4kECRMQ6xWV6CT/btAgMBAAECgYBFaYiHL2NH2CDgRE0lNAmotRTM
    AUBHj+X24oxAE5DA17jrIGvhm1H14mZF4LYGOMri46+5QrRLZ/HQukG6ITPsfd60
    PdsRmqyUh+xBkkc1kUgjdHx9ei3psGOpaS4qO3a9YqTes2ioImGo7HOdbvNi+Ipz
    xncaDCUMrvwmKJxuoQJBAPbwLjmaC/GpXINkVYtBEKINGZu42IfkXrqOUV7C0iaU
    5pBpPqehMMLwl9WRmvp3xzFwoY8CEQuzmm5nMX4DOCsCQQDFWv2GuRGkhKBPt53Z
    UbKEltpkCNX33dMDdUAGEHnkPkCRNCRcpxAw921P+NuPFsafw41k+3Qi2oVGBb9D
    halHAkEAw8reK+fbjooFg1x7g0VcpdCTPGhMrzrAbVTIacU5EURAp8H63risy/Qt
    vzWK1ws/khDG2HgAAfIvAViq4ko1LwJBAIOG8aIA4zYuwZx/Ne7omL3uv5udm+Q2
    bPRIByRDhMjNiEB9bKJnIM5RiAOdSc5iEnvVWv1q6+pykhGpsN9yS+8CQEgqigV+
    sKG2kaDztx7kOPV94O2IvlceY0llkGyjT55z78Bnu4sTe6EuviDoOww07NbvDZhv
    jiqWngR+SlSRhak=
    -----END PRIVATE KEY-----
    

    为了方便使用我们可以把他们放到两个不同文件中

    2、导入依赖

    encrypt: ^4.0.0
    

    3、导入头文件

    import 'package:flutter/services.dart' show rootBundle;
    import 'package:encrypt/encrypt.dart';
    

    4、代码实现一

    加密实现:
      static Future<String> encodeString(String content) async{
        var publicKeyStr = await rootBundle.loadString('assets/data/rsa_public_key.pem');
        var publicKey = RSAKeyParser().parse(publicKeyStr);
        final encrypter = Encrypter(RSA(publicKey: publicKey));     
        return await encrypter.encrypt(content).base64.toUpperCase();
      }
    
    解密实现:
      static Future<String> decodeString(String content) async{
        var publicKeyStr = await rootBundle.loadString('assets/data/rsa_private_key.pem');
        var publicKey =  RSAKeyParser().parse(publicKeyStr);
        final encrypter = Encrypter(RSA(publicKey: publicKey));     
        return await encrypter.decrypt(Encrypted.fromBase64(content));
      }
    

    细心的朋友会发现当我们的当字符串长度超过117,这时候会报溢出。我们来继续完善我们的代码,也就是说字符串长度超过117就需要做分段加密 和分段解密。

    5、代码实现二

    分段加密实现:
      static Future<String> encodeString(String content) async{
        var publicKeyStr = await rootBundle.loadString('assets/data/rsa_public_key.pem');
        var publicKey = RSAKeyParser().parse(publicKeyStr);
        final encrypter = Encrypter(RSA(publicKey: publicKey));
    
        List<int> sourceBytes = utf8.encode(content);
        int inputLen = sourceBytes.length;
        int maxLen = 117;
        List<int> totalBytes = List();
        for (var i = 0; i < inputLen; i += maxLen) {
          int endLen = inputLen - i;
          List<int> item;
          if (endLen > maxLen) {
            item = sourceBytes.sublist(i, i + maxLen);
          }
          else {
            item = sourceBytes.sublist(i, i + endLen);
          }
          totalBytes.addAll(encrypter.encryptBytes(item).bytes);
        }
        return base64.encode(totalBytes);
    //       return await encrypter.encrypt(content).base64.toUpperCase();
      }
    
    分段解密实现:
      static Future<String> decodeString(String content) async{
        var publicKeyStr = await rootBundle.loadString('assets/data/rsa_private_key.pem');
        var publicKey =  RSAKeyParser().parse(publicKeyStr);
        final encrypter = Encrypter(RSA(publicKey: publicKey));
    
        Uint8List sourceBytes = base64.decode(content);
        int inputLen = sourceBytes.length;
        int maxLen = 128;
        List<int> totalBytes = List();
        for (var i = 0; i < inputLen; i += maxLen) {
          int endLen = inputLen - i;
          Uint8List item;
          if (endLen > maxLen) {
            item = sourceBytes.sublist(i, i + maxLen);
          } else {
            item = sourceBytes.sublist(i, i + endLen);
          }
          totalBytes.addAll(encrypter.decryptBytes(Encrypted(item)));
        }
        return utf8.decode(totalBytes);
    //        return await encrypter.decrypt(Encrypted.fromBase64(content));
      }
    

    6、代码调用

    String encode = await MyEncrypt.encodeString(jsonString);
    print("encode:$encode");
    String decode = await MyEncrypt.decodeString(encode);
    print("decode:$decode");
    

    7、问题深究

    现实中经常出现
    上传数据:客户端使用公钥加密,服务端使用私钥解密;
    下发数据: 服务端使用私钥加密,客户端使用公钥解密。
    这时候我们需要怎么处理呢?答案在下一篇。

    下一篇
    Flutter RSA加密、解密之我见二

    相关文章

      网友评论

        本文标题:Flutter RSA加密、解密之我见一

        本文链接:https://www.haomeiwen.com/subject/yfquahtx.html