前言
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 中的常用场景:
在整个计算机范畴,数据加密的算法十分多,但是在 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