加密是各个平台开发过程中不可避免接触到了,本次就讲解 flutter 中比较常见的加密 base64、MD5、SHA、HMAC、AES
base64
base64加密也是开发过程中经常使用的,其为对称加密,因此对于需要加密传递信息的时候一般都会用到,且其来自 dart 的convert库,因此不需要引入第三方,当然纯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);
}
这样就完成了加密
最后
有不明白的可以快速尝试一下,文档地址也发了,一些不好用的或者文档不全、有问题的可以联系作者哈