Flutter AES/RAS 加解密工具类

因项目需要用到加解密,然后研究了下flutter大部分是用原生实现加解密的,但是这样不是我想要的,后面找资料发现dart有一个加密工具 encrypt 。然后研究了下,可以实现我们大部分加解密。

一、介绍

使用Dart实现加解密,有对称加密AES,非对称加密RSA。
工具类封装了AES加解密,RSA加解密和数字签名,RSA也实现分段加解密。

一、导包

  # 加密 https://pub.dev/packages/encrypt
  encrypt: ^5.0.1

二、工具类

import 'dart:convert';
import 'dart:typed_data';

import 'package:encrypt/encrypt.dart';
import 'package:flutter/services.dart';
import 'package:pointycastle/asymmetric/api.dart';

/// Created by XieXin on 2021/8/13.
/// 加密工具类
class EncryptUtils {
  ///aes
  static late Key _keyAes;
  static late Encrypter _encryptAes;
  static IV _ivAes = IV.fromLength(16);

  ///rsa
  static late RSAPublicKey _publicKey;
  static late RSAPrivateKey _privateKey;
  static late Encrypter _encryptRsa;
  static late Signer _signer;

  /// Rsa加密最大长度
  static const int MAX_ENCRYPT_BLOCK = 117;

  /// Rsa解密最大长度
  static const int MAX_DECRYPT_BLOCK = 128;

  ///初始化AES加密启动时调用
  static Future<void> initAes(
    String key, {
    mode = AESMode.sic,
    padding = 'PKCS7',
  }) async {
    if (key.length == 16 || key.length == 24 || key.length == 32) {
      _keyAes = Key.fromUtf8(key);
      _encryptAes = Encrypter(AES(_keyAes, mode: mode, padding: padding));
      return;
    }
    print("密钥长度为16/24/32位");
  }

  ///初始化RAS加密启动时调用
  static Future<void> initRsa(String publicPath, String privatePath) async {
    String publicKeyString = await rootBundle.loadString(publicPath);
    String privateKeyString = await rootBundle.loadString(privatePath);
    _publicKey = RSAKeyParser().parse(publicKeyString) as RSAPublicKey;
    _privateKey = RSAKeyParser().parse(privateKeyString) as RSAPrivateKey;

    _encryptRsa = Encrypter(
      RSA(publicKey: _publicKey, privateKey: _privateKey),
    );
    _signer = Signer(RSASigner(RSASignDigest.SHA256,
        publicKey: _publicKey, privateKey: _privateKey));
  }

  ///Aes加密
  static String encryptAes(String context) {
    return _encryptAes.encrypt(context, iv: _ivAes).base64;
  }

  ///Aes解密
  static String decryptAes(String context) {
    return _encryptAes.decrypt(Encrypted.fromBase64(context), iv: _ivAes);
  }

  ///公钥Rsa加密
  static String encryptRsa(String context) {
    // 原始字符串转成字节数组
    List<int> sourceBytes = utf8.encode(context);
    // 数据长度
    int inputLen = sourceBytes.length;
    // 缓存数组
    List<int> cache = [];
    // 分段加密 步长为MAX_ENCRYPT_BLOCK
    for (var i = 0; i < inputLen; i += MAX_ENCRYPT_BLOCK) {
      // 剩余长度
      int endLen = inputLen - i;
      List<int> item;
      if (endLen > MAX_ENCRYPT_BLOCK) {
        item = sourceBytes.sublist(i, i + MAX_ENCRYPT_BLOCK);
      } else {
        item = sourceBytes.sublist(i, i + endLen);
      }
      // 加密后对象转换成数组存放到缓存
      cache.addAll(_encryptRsa.encryptBytes(item).bytes);
    }
    // 加密后数组转换成base64编码并返回
    String en = base64.encode(cache);
    return en;
  }

  ///私钥Rsa解密
  static String decryptRsa(String data) {
    // 原始字符串转成字节数组
    Uint8List sourceBytes = base64.decode(data);
    // 数据长度
    int inputLen = sourceBytes.length;
    // 缓存数组
    List<int> cache = [];
    // 分段解密 步长为MAX_DECRYPT_BLOCK
    for (var i = 0; i < inputLen; i += MAX_DECRYPT_BLOCK) {
      // 剩余长度
      int endLen = inputLen - i;
      Uint8List item;
      if (endLen > MAX_DECRYPT_BLOCK) {
        item = sourceBytes.sublist(i, i + MAX_DECRYPT_BLOCK);
      } else {
        item = sourceBytes.sublist(i, i + endLen);
      }
      // 解密后存放到缓存
      cache.addAll(_encryptRsa.decryptBytes(Encrypted(item)));
    }
    // 解密后数组解码并返回
    String decode = utf8.decode(cache);
    return decode;
  }

  ///用私钥对信息生成数字签名
  static String sign(String data) {
    return _signer.sign(data).base64;
  }

  ///校验数字签名
  static bool verify(String data, String sign) {
    return _signer.verify64(data, sign);
  }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容