【FlutterUtilCode】Flutter工具篇之EncryptUtils
前言
FlutterUtilCode 是一个 Flutter 工具类集合插件,封装了常用的工具类和函数,方便开发者调用。
本篇是 Flutter工具篇之EncryptUtils,系列文章内容主要介绍插件中工具类的功能、用法和代码实现等,感兴趣的同学可以持续关注。
FlutterUtilCode 系列(七)—— Flutter工具篇之EncryptUtils
FlutterUtilCode 系列(六)—— Flutter工具篇之AppUtils
FlutterUtilCode 系列(五)—— Flutter工具篇之PathUtils
FlutterUtilCode 系列(四)—— Flutter工具篇之DeviceUtils
FlutterUtilCode 系列(三)—— Flutter工具篇之UuidUtils
FlutterUtilCode 系列(二)—— Flutter工具篇之ToastUtils
FlutterUtilCode 系列(一)—— Flutter工具篇之LogUtils、SharedPerfsUtils
加密工具类-EncryptUtils
数据加密在 App 开发中广泛应用,其不仅可以有效保护用户隐私和数据安全,还可以提高应用程序的安全性和可靠性。以下是数据加密在 App 中的常用场景:
- 用户密码加密:将用户密码进行哈希或者加密,以保证用户的登录信息安全。
- 网络传输加密:使用SSL/TLS等协议对应用程序与服务器之间的通信进行加密,以防止网络窃听和恶意攻击。
- 本地存储加密:对应用程序中涉及用户隐私的本地存储数据进行加密,例如支付信息、地理位置等。
- 应用程序代码保护:使用剧烈数据加密对应用程序代码和资源文件进行保护,以避免反编译和篡改操作。
- 加密算法选择:在应用程序中选择适合的加密算法,如AES加密、RSA加密、HMAC消息认证等。
- 数字签名验证:使用数字签名来验证应用程序的合法性和完整性,以防止被植入恶意代码或者篡改。
在整个计算机领域,数据加密的算法非常多,但是在 App 中一般只会用到常见的几种。今天我们的加密工具类 EncryptUtils 将会实现以下常用的加密算法:MD5、RC4、AES、RSA、SHA256withRSA、MD5withRSA。
一、代码实现
1.1 MD5
MD5(Message Digest Algorithm 5) 是一种常见的哈希函数,可将任意长度的消息压缩为一个128位的摘要(Digest),通常用于数据完整性校验、数字签名等场景。
对于 MD5 加密,这里用到了 crypto 插件。通过将字符串转换成 Uint8List ,让 crypto 完成 MD5 的转换。代码如下:
/// MD5加密
/// [content] 加密内容
static String md5Encrypt(String content) {
Uint8List uint8list = const Utf8Encoder().convert(content);
Digest digest = md5.convert(uint8list);
return digest.toString();
}
1.2 RC4
RC4(Rivest Cipher 4) 是一种流密码(Stream Cipher),由Ron Rivest在1987年设计。它基于伪随机数生成器(Pseudo-Random Number Generator,PRNG)产生的密钥流来对明文进行加/解密。
由于目前没有找到有对应的插件,这里我们自己实现 RC4 加密算法。
第一步,生成加密 key。
final Uint8List _s = Uint8List(256);
int _i = 0;
int _j = 0;
void setKey(Uint8List key) {
for (int i = 0; i < 256; i++) {
_s[i] = i;
}
int j = 0;
for (int i = 0; i < 256; i++) {
j = (j + _s[i] + key[i % key.length]) % 256;
swap(i, j);
}
_i = 0;
_j = 0;
}
void swap(int i, int j) {
int temp = _s[i];
_s[i] = _s[j];
_s[j] = temp;
}
第二步,对内容进行加密,取 data 和 key 的异或运算为结果。
/// 加密
/// [data]数据
Uint8List crypt(Uint8List data) {
Uint8List result = Uint8List(data.length);
for (int k = 0; k < data.length; k++) {
result[k] = data[k] ^ next();
}
return result;
}
int next() {
_i = (_i + 1) % 256;
_j = (_j + _s[_i]) % 256;
swap(_i, _j);
return _s[(_s[_i] + _s[_j]) % 256];
}
第三步,使用定义的 RC4 对象进行加密。
/// RC4加密
/// [content] 明文
static String rc4Encrypt(String content, String keyStr) {
RC4 rc4 = RC4(keyStr);
Uint8List data = Uint8List.fromList(content.codeUnits);
Uint8List crypt = rc4.crypt(data);
return base64Encode(crypt);
}
第四步,使用定义的 RC4 对象进行解密。
/// RC4解密
/// [content] 密文
static String rc4Decrypt(String content, String keyStr) {
RC4 rc4 = RC4(keyStr);
Uint8List data = base64Decode(content);
Uint8List crypt = rc4.crypt(data);
return utf8.decode(crypt);
}
1.3 AES
AES(Advanced Encryption Standard) 是一种高级加密标准,是目前最常用的对称加密算法之一,被广泛应用于数据保护、网络安全等领域。它支持三个密钥长度:128位、192位和256位,其中128位密钥是最常用的。
这里我们使用 encrypt 插件来实现 AES 加密/解密。
- AES加密,默认[AESMode.ecb]加密方式
/// AES加密, 默认[AESMode.ecb]加密方式
/// [content] 明文
/// [aesKey] 秘钥
static aesEncrypt(String content, String keyStr, [AESModeType type = AESModeType.ecb]) {
final key = Key.fromUtf8(keyStr);
final iv = IV.fromLength(16);
AESMode mode = AESMode.values.firstWhere((element) => element.name == type.name, orElse: () => AESMode.ecb);
final encryptor = Encrypter(AES(key, mode: mode));
final encrypted = encryptor.encrypt(content, iv: iv);
return encrypted.base64;
}
- AES解密,默认[AESMode.ecb]加密方式
/// AES解密, 默认[AESMode.ecb]加密方式
/// [content] 密文
/// [aesKey] 秘钥
static aesDecrypt(String content, String keyStr, [AESModeType type = AESModeType.ecb]) {
final key = Key.fromUtf8(keyStr);
final iv = IV.fromLength(16);
AESMode mode = AESMode.values.firstWhere((element) => element.name == type.name, orElse: () => AESMode.ecb);
final encryptor = Encrypter(AES(key, mode: mode));
final encrypted = Encrypted.fromBase64(content);
final decrypted = encryptor.decrypt(encrypted, iv: iv);
return decrypted;
}
1.4 RSA
RSA(Rivest-Shamir-Adleman) 是一种非对称加密算法,广泛用于数据加密和数字签名。
这里我们同样使用 encrypt 插件来实现 RSA 加密/解密。
- RSA加密,密钥格式为[pkcs8]
/// RSA加密算法加密,秘钥格式为[pkcs8]
/// [content]明文
/// [publicKeyStr]公钥
static String rsaEncrypt(String content, String publicKeyStr) {
final parser = RSAKeyParser();
String publicKeyString = _transformPem(publicKeyStr);
RSAPublicKey publicKey = parser.parse(publicKeyString) as RSAPublicKey;
final encryptor = Encrypter(RSA(publicKey: publicKey));
final encrypted = encryptor.encrypt(content);
return encrypted.base64;
}
- RSA解密,密钥格式为[pkcs8]
/// RSA加密算法解密,秘钥格式为[pkcs8]
/// [encryptedStr]密文,base64编码
/// [privateKeyStr]私钥
static String rsaDecrypt(String encryptedStr, String privateKeyStr) {
final parser = RSAKeyParser();
String publicKeyString = _transformPem(privateKeyStr, isPublic: false);
RSAPrivateKey privateKey = parser.parse(publicKeyString) as RSAPrivateKey;
final encryptor = Encrypter(RSA(privateKey: privateKey));
final encrypted = Encrypted.fromBase64(encryptedStr);
final decrypted = encryptor.decrypt(encrypted);
return decrypted;
}
1.5 SHA256withRSA
SHA256withRSA 是一种签名算法,结合了 SHA-256哈希函数 和 RSA非对称加密算法。它用于生成数字签名,并验证数字签名的完整性和真实性。
- SHA256withRSA签名,密钥格式为[pkcs8]
/// sha256withRSA签名,秘钥格式为[pkcs8]
/// [content]明文
/// [privateKeyStr]私钥
static String sha256withRSASign(String content, String privateKeyStr) {
RSAKeyParser parser = RSAKeyParser();
Signer signer;
// 初始化私钥
String privateKeyString = _transformPem(privateKeyStr, isPublic: false);
RSAPrivateKey privateKey = parser.parse(privateKeyString) as RSAPrivateKey;
signer = Signer(RSASigner(RSASignDigest.SHA256, privateKey: privateKey));
var sign = signer.sign(content).base64;
return sign;
}
- SHA256withRSA验签,密钥格式为[pkcs8]
/// sha256withRSA验签,秘钥格式为[pkcs8]
/// [content]明文
/// [signature]签名
/// [publicKeyStr]公钥
static bool sha256withRSAVerify(String content, String signature, String publicKeyStr) {
RSAKeyParser parser = RSAKeyParser();
Signer signer;
// 初始化公钥
String publicKeyString = _transformPem(publicKeyStr);
RSAPublicKey publicKey = parser.parse(publicKeyString) as RSAPublicKey;
signer = Signer(RSASigner(RSASignDigest.SHA256, publicKey: publicKey));
// 验签
var verify = signer.verify(content, Encrypted.from64(signature));
return verify;
}
1.6 MD5withRSA
MD5withRSA 与 SHA256withRSA 类似,也是一种签名算法,不同之处在于其是 MD5哈希函数 和 RSA非对称加密算法 结合。同样用于生成数字签名,并验证数字签名的完整性和真实性。
这里我们使用 fast_rsa 插件来实现 MD5withRSA 签名
- MD5withRSA签名,密钥格式为[pkcs8]
/// md5withRSA签名,秘钥格式为[pkcs8]
/// [content]明文
/// [privateKeyStr]私钥
static Future<String> md5withRSASign(String content, String privateKeyStr) async {
// 初始化私钥
String privateKeyString = _transformPem(privateKeyStr, isPublic: false);
String privateKey = await fast_rsa.RSA.convertPrivateKeyToPKCS1(privateKeyString);
var sign = await fast_rsa.RSA.signPKCS1v15(content, fast_rsa.Hash.MD5, privateKey);
return sign;
}
- MD5withRSA验签,密钥格式为[pkcs8]
/// md5withRSA验签,秘钥格式为[pkcs8]
/// [content]明文
/// [signature]签名
/// [publicKeyStr]公钥
static Future<bool> md5withRSAVerify(String content, String signature, String publicKeyStr) async {
// 初始化公钥
String publicKeyString = _transformPem(publicKeyStr);
String publicKey = await fast_rsa.RSA.convertPublicKeyToPKCS1(publicKeyString);
var verify = await fast_rsa.RSA.verifyPKCS1v15(signature, content, fast_rsa.Hash.MD5, publicKey);
return verify;
}
二、使用案例
EncryptUtils 的使用也是非常简单,一行代码调用即可:
// MD5加密
String md5 = EncryptUtils.md5Encrypt(content);
// RC4加密/解密
String encrypt = EncryptUtils.rc4Encrypt(content, rc4Key);
String decrypt = EncryptUtils.rc4Decrypt(encrypt, rc4Key);
// AES加密/解密
String encrypt = EncryptUtils.aesEncrypt(content, aesKey);
String decrypt = EncryptUtils.aesDecrypt(encrypt, aesKey);
// RSA加密/解密
String encrypt = EncryptUtils.rsaEncrypt(content, publicKey);
String decrypt = EncryptUtils.rsaDecrypt(encrypt, privateKey);
// SHA256withRSA 签名/验签
String sign = EncryptUtils.sha256withRSASign(content, privateKey);
bool verify = EncryptUtils.sha256withRSAVerify(content, sign, publicKey);
// MD5withRSA 签名/验签
String sign = await EncryptUtils.md5withRSASign(content, privateKey);
bool verify = await EncryptUtils.md5withRSAVerify(content, sign, publicKey);
运行结果 :

三、测试用例
测试用例 encrypt_test :
// MD5加密
test('MD5', () {
String md5 = EncryptUtils.md5Encrypt(content);
expect(md5, 'fc3ff98e8c6a0d3087d515c0473f8677');
});
// RC4加密/解密
test('RC4', () {
String encrypt = EncryptUtils.rc4Encrypt(content, rc4Key);
String decrypt = EncryptUtils.rc4Decrypt(encrypt, rc4Key);
expect(encrypt, 'YrlMGzqCagCj9+ff');
expect(decrypt, content);
});
// AES加密/解密
test('AES', () {
String encrypt = EncryptUtils.aesEncrypt(content, aesKey);
String decrypt = EncryptUtils.aesDecrypt(encrypt, aesKey);
expect(encrypt, 'XkxSOtpoErJzTyW5/6sGNA==');
expect(decrypt, content);
});
// RSA加密/解密
test('RSA', () async {
String encrypt = EncryptUtils.rsaEncrypt(content, publicKey);
String decrypt = EncryptUtils.rsaDecrypt(encrypt, privateKey);
debugPrint('encrypt: $encrypt');
expect(decrypt, content);
});
// SHA256withRSA 签名/验签
test('SHA256withRSA', () {
String sign = EncryptUtils.sha256withRSASign(content, privateKey);
bool verify = EncryptUtils.sha256withRSAVerify(content, sign, publicKey);
debugPrint('sign: $sign');
expect(verify, true);
});
// MD5withRSA 签名/验签
// 若出现库无法找到问题,需要将example项目下的build文件拷贝到根目录下
test('MD5withRSA', () async {
String sign = await EncryptUtils.md5withRSASign(content, privateKey);
bool verify = await EncryptUtils.md5withRSAVerify(content, sign, publicKey);
debugPrint('sign: $sign');
expect(verify, true);
});
运行结果:
结语
好了,今天的工具类整理文章就到这里,目前插件已发布到 Pub 中,欢迎大家体验。
如果觉得这篇文章对你有所帮助的话,不要忘记一键三连哦,大家的点赞是我更新的动力🥰。
Pub: flutter_util_code
项目源码:FlutterUtilCode
使用案例:Example
转载自:https://juejin.cn/post/7250029395023446072