項(xiàng)目中是服務(wù)端持有私鑰,客戶端持有公鑰;
客戶端使用公鑰加密,并使用公鑰解密服務(wù)端 用私鑰加密的數(shù)據(jù)。
網(wǎng)上相關(guān)的資料實(shí)在再少,終于功夫不負(fù)有心人,被我找到了。附上代碼。
先引入包 :
https://pub-web.flutter-io.cn/packages/encrypt
https://pub.dev/packages/pointycastle
encrypt: ^5.0.1
pointycastle: ^3.1.1
import 'dart:convert';
import 'package:encrypt/encrypt.dart';
import 'package:flutter/services.dart';
import 'package:pointycastle/api.dart';
import 'package:pointycastle/asymmetric/api.dart';
import 'package:pointycastle/asymmetric/pkcs1.dart';
import 'package:pointycastle/asymmetric/rsa.dart';
// import 'package:pointycastle/export.dart';
class EncryptUtil {
// Rsa加密最大長(zhǎng)度(密鑰長(zhǎng)度/8-11)
static const int MAX_ENCRYPT_BLOCK = 245;
// Rsa解密最大長(zhǎng)度(密鑰長(zhǎng)度/8)
static const int MAX_DECRYPT_BLOCK = 256;
//公鑰分段加密
static Future encodeString(String content) async {
//加載公鑰字符串
final publicPem = await rootBundle.loadString(這里寫密鑰路徑);
//創(chuàng)建公鑰對(duì)象
RSAPublicKey publicKey = RSAKeyParser().parse(publicPem) as RSAPublicKey;
//創(chuàng)建加密器
final encrypter = Encrypter(RSA(publicKey: publicKey));
//分段加密
// 原始字符串轉(zhuǎn)成字節(jié)數(shù)組
List<int> sourceBytes = utf8.encode(content);
//數(shù)據(jù)長(zhǎng)度
int inputLength = sourceBytes.length;
// 緩存數(shù)組
List<int> cache = [];
// 分段加密 步長(zhǎng)為MAX_ENCRYPT_BLOCK
for(int i=0;i<inputLength;i+=MAX_ENCRYPT_BLOCK){
//剩余長(zhǎng)度
int endLen = inputLength-i;
List<int> item;
if(endLen > MAX_ENCRYPT_BLOCK){
item = sourceBytes.sublist(i,i+MAX_ENCRYPT_BLOCK);
}else {
item = sourceBytes.sublist(i,i+endLen);
}
// 加密后對(duì)象轉(zhuǎn)換成數(shù)組存放到緩存
cache.addAll(encrypter.encryptBytes(item).bytes);
}
return base64Encode(cache);
}
//公鑰分段解密
static Future decodeString(String content) async{
//加載公鑰字符串
final publicPem = await rootBundle.loadString(這里寫密鑰路徑);
//創(chuàng)建公鑰對(duì)象
RSAPublicKey publicKey = RSAKeyParser().parse(publicPem) as RSAPublicKey;
AsymmetricBlockCipher cipher = PKCS1Encoding(RSAEngine());
cipher.init(false, PublicKeyParameter<RSAPublicKey>(publicKey));
//分段解密
//原始數(shù)據(jù)
List<int> sourceBytes = base64Decode(content);
//數(shù)據(jù)長(zhǎng)度
int inputLength = sourceBytes.length;
// 緩存數(shù)組
List<int> cache = [];
// 分段解密 步長(zhǎng)為MAX_DECRYPT_BLOCK
for(var i=0;i<inputLength;i+=MAX_DECRYPT_BLOCK){
//剩余長(zhǎng)度
int endLen =inputLength - i;
List<int> item;
if(endLen > MAX_DECRYPT_BLOCK){
item = sourceBytes.sublist(i,i+MAX_DECRYPT_BLOCK);
}else {
item = sourceBytes.sublist(i,i+endLen);
}
//解密后放到數(shù)組緩存
cache.addAll(cipher.process(Uint8List.fromList(item)));
}
return utf8.decode(cache);
}
}
參考資料:
https://stackoverflow.com/questions/61858252/flutter-how-to-decrypt-a-rsa-private-key-encrypted-string-if-we-have-rsa-publi
https://github.com/leocavalcante/encrypt/issues/180
http://m.itdecent.cn/p/0194b99a4b3d