flutter-常见加密以及三方加密库(base64、MD5、SHA、AES等)

4,022 阅读3分钟

加密是各个平台开发过程中不可避免接触到了,本次就讲解 flutter 中比较常见的加密 base64、MD5、SHA、HMAC、AES

案例demo地址

base64

base64加密也是开发过程中经常使用的,其为对称加密,因此对于需要加密传递信息的时候一般都会用到,且其来自 dartconvert库,因此不需要引入第三方,当然纯dart代码也可以引入

import 'dart:convert';

void encryptBase64(String str) {
    print("Base64加密前文本:" + str);
    var content = utf8.encode(str);
    var digest = base64Encode(content);
    base64String = digest.toString();
    print("Base64加密后文本:" + base64String);
}

void decryptBase64() {
    print("Base64解密前文本:" + base64String);
    base64String = String.fromCharCodes(base64Decode(base64String));
    print("Base64解密后文本:" + base64String);
}

crypto(MD5、SHA、HMAC、HMAC)

下面常见 MD5、SHA、HMAC等加密,用的是三方库 crypto

使用 crypto 的时候需要将字符串转化成成指定类型,因此需要借用 dart:convert

下面就是常见的 md5、sha,逻辑差不多,剩下的就省略了

import 'dart:convert';
import 'package:crypto/crypto.dart';

//MD5
void encryptMd5(String str) {
 print("Md5加密前文本:" + str);
 //转化字符串
 final utf = utf8.encode(str);
 //加密
 final digest = md5.convert(utf);
 final encryptStr = digest.toString();
 print("Md5加密后文本:" + encryptStr);
}

//SHA1
void encryptSHA1(String str) {
 print("SHA加密前文本:" + str);
 final utf = utf8.encode(str);
 final digest = sha1.convert(utf);
 final encryptStr = digest.toString();
 print("SHA加密后文本:" + encryptStr);
}

void encryptSHA256(String str) {
 print("SHA256加密前文本:" + str);
 final utf = utf8.encode(str);
 final digest = sha256.convert(utf);
 final encryptStr = digest.toString();
 print("SHA256加密后文本:" + encryptStr);
}

有时候我们需要根据类型动态选择算法,此时也可以较为简单的实现

//根据参数选择加密
//仔细看可以看到 md5、sha等都继承 Hash 抽象类,声明 Hash对象赋值类型,可以直接动态切换
void encryptByType(String type, String str) {
  Hash hasher;
  switch (type) {
    case 'md5':
      hasher = md5;
      break;
    case 'sha1':
      hasher = sha1;
      break;
    case 'sha256':
      hasher = sha256;
      break;
    default:
      //其他就默认512吧
      hasher = sha512;
      return;
  }
  print("$type加密前文本:" + str);
  final utf = utf8.encode(str);
  final digest = hasher.convert(utf);
  final encryptStr = digest.toString();
  print("加密后文本:" + encryptStr);
}

HMAC

HMAC算法,以key-value的形式对字符串进行加密,因此安全系数较高,也是很多开发者在接口身份校验防篡改方案比较中意的方案

下面就是以 SHA256的 HMAC 算法为例,由于比较相似,就不介绍其他的了

//HMAC加密,即带有哈希的加密算法,使用键值进行加密
void encryptHMACSHA256(String hmacKey, String hmacValue) {
  print("加密前文本:key:$hmacKey value:$hmacValue");
  var key = utf8.encode(hmacKey);
  var bytes = utf8.encode(hmacValue);
  //第一个参数算法类型就不多说了
  var hmacSha256 = Hmac(sha256, key); // HMAC-SHA256
  var digest = hmacSha256.convert(bytes);
  final encryptStr = digest.toString();
  print("SHA256的HMAC加密后文本:key:$hmacKey value:$encryptStr");
}

cryptography(MD5、SHA、HMAC、HMAC)

crypto 类似,不过其拥有更多种加密算法,cryptography仓库地址cryptography文档地址

我试了一下,不过一部分文档不全,写着会有问题,且没有 md5,如果没有其他要使用的,可以被 crypto代替(毕竟算法算了,代码也少了)

话不多说,直接上代码,不过里面默认返回的类型里面只有字节数组,且作者写的 toString方法的也没有转化成16进制字符串,而是直接拼成了数组(想转化成16进制字符串的话,需要我们将这数组数组转化为字符串)

//只有一个加密这么导入就行了
import 'package:cryptography/cryptography.dart'
//如果同时使用了两个加密,很容易冲突,使用模块化导出即可
import 'package:cryptography/cryptography.dart' as cryptography;

//SHA1加密
Future<void> encryptSHA1ByCryptography(String str) async {
  print("SHA1ByCryptograph加密前文本:" + str);
  final message = utf8.encode(str);
  final algorithm = cryptography.Sha1();
  final hash = await algorithm.hash(message);
  //转化成16进制字符串
  final encryptStr = getHexString(hash.bytes);
  print("SHA1ByCryptograph加密后文本:" + encryptStr);
}

//SHA256加密
Future<void> encryptSHA256ByCryptography(String str) async {
  print("SHA256ByCryptograph加密前文本:" + str);
  final message = utf8.encode(str);
  final algorithm = cryptography.Sha256();
  final hash = await algorithm.hash(message);
  final encryptStr = getHexString(hash.bytes);
  print("SHA256ByCryptograph加密后文本:" + encryptStr);
}

//SHA256的HMAC加密
Future<void> encryptHMACSHA256ByCryptography(String hmacKey, String hmacValue) async {
  print("SHA256ByCryptograph加密前文本:key:$hmacKey value:$hmacValue");
  var key = utf8.encode(hmacKey);
  final bytes = utf8.encode(hmacValue); //这个转化的是accii码走的
  final secretKey = cryptography.SecretKey(key);

  final hmac = cryptography.Hmac.sha256();
  final mac = await hmac.calculateMac(
    bytes,
    secretKey: secretKey,
  );
  //返回的内容是16进制数组,需要转化成16进制字符串,因此不能使用utf8.decode
  final encryptStr = getHexString(mac.bytes);
  print("SHA256ByCryptograph加密后文本:" + encryptStr);
}

//将16进制数组转化成字符串
String getHexString(List<int> ints) {
  return ints.map((e) {
    //toRadixString 转化 成 16 进制
    String text = e.toRadixString(16);
    return text.length > 1 ? text : '0$text';
  }).join('');
}

encrypt(AES加解密)

前面的两个库,不是不支持AES 就是目前文档不友好,那么我们另选其他,就只能用这个 encrypt 了,个人测试了下,使用良好

使用前先介绍下三个参数,data、key、iv,就是我们传递的 content、keyStr、ivStr

data:被加密的字符串或字节数组

key:用于加密的字符串或字节数组

iv:加密用的偏移量

其中 key、iv 两者的位数都要相同,且为 8的倍数,一般为 8,16,32

话不多说直接上代码了

//只有一个加密这么导入就行了
import 'package:encrypt/encrypt.dart';
//如果同时使用了两个加密,很容易冲突,使用模块化导出即可
import 'package:encrypt/encrypt.dart' as encrypt;


/content:被加密数据,keyStr:加密key, ivStr
void encryptAES(String content, String keyStr, String ivStr) {
  print("AES加密前的文本:" + content);
  final plainText = content;
  final key = encrypt.Key.fromUtf8(keyStr);
  final iv = encrypt.IV.fromUtf8(ivStr);
  final encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc));
  final encrypted = encrypter.encrypt(plainText, iv: iv);
  final encryptStr = encrypted.base64;

  print("AES加密后的文本:" + encryptStr);
}

void decryptAES(String content, String keyStr, String ivStr) {
  print("AES解密前的文本:" + content);
  final key = encrypt.Key.fromUtf8(keyStr);
  final iv = encrypt.IV.fromUtf8(ivStr);
  final encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc));
  final decrypted = encrypter.decrypt64(content, iv: iv);
  print("AES解密后的文本:" + decrypted);
}

这样就完成了加密

最后

有不明白的可以快速尝试一下,文档地址也发了,一些不好用的或者文档不全、有问题的可以联系作者哈