import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'dart:math'; import 'package:cookie_jar/cookie_jar.dart'; import 'package:crypto/crypto.dart'; import 'package:encrypt/encrypt.dart' as encrypt; import 'package:encrypt/encrypt_io.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:path_provider/path_provider.dart'; import 'package:pointycastle/asymmetric/api.dart'; import 'package:pointycastle/export.dart'; import 'package:pointycastle/src/platform_check/platform_check.dart'; import 'api.dart'; import 'global.dart'; class RSAPublicKeyStore extends RSAPublicKey { RSAPublicKeyStore(BigInt modulus, BigInt exponent) : super(modulus, exponent); Map toJson() => {"modulus": modulus.toString(), "exponent": exponent.toString()}; factory RSAPublicKeyStore.fromJson(Map map) { return RSAPublicKeyStore(BigInt.parse(map["modulus"]), BigInt.parse(map["exponent"])); } Future save(String key) async { try { final storage = FlutterSecureStorage(); storage.write(key: key, value: jsonEncode(toJson())); } catch (e) { debug('save $key error: $e'); } } static Future load(String key) async { RSAPublicKeyStore? result; try { final storage = FlutterSecureStorage(); final json = await storage.read(key: key); result = RSAPublicKeyStore.fromJson(jsonDecode(json!)); } catch (e) { debug('load $key error: $e'); } return result; } } class RSAPrivateKeyStore extends RSAPrivateKey { RSAPrivateKeyStore(BigInt modulus, BigInt privateExponent, BigInt p, BigInt q) : super(modulus, privateExponent, p, q); Map toJson() => { "modulus": modulus.toString(), "privateExponent": privateExponent.toString(), "p": p.toString(), "q": q.toString(), }; factory RSAPrivateKeyStore.fromJson(Map map) { return RSAPrivateKeyStore( BigInt.parse(map["modulus"]), BigInt.parse(map["privateExponent"]), BigInt.parse(map["p"]), BigInt.parse(map["q"]), ); } Future save(String key) async { try { final storage = FlutterSecureStorage(); storage.write(key: key, value: jsonEncode(toJson())); } catch (e) { debug('save $key error: $e'); } } static Future load(String key) async { RSAPrivateKeyStore? result; try { final storage = FlutterSecureStorage(); final json = await storage.read(key: key); result = RSAPrivateKeyStore.fromJson(jsonDecode(json!)); } catch (e) { debug('load $key error: $e'); } return result; } } AsymmetricKeyPair generateRSAKeyPair({SecureRandom? secureRandom, int bitLength = 2048}) { // Create an RSA key generator and initialize it secureRandom ??= getSecureRandom(); final keyGen = RSAKeyGenerator() ..init(ParametersWithRandom(RSAKeyGeneratorParameters(BigInt.parse('65537'), bitLength, 64), secureRandom)); // Use the generator final pair = keyGen.generateKeyPair(); // Cast the generated key pair into the RSA key types final myPublic = pair.publicKey as RSAPublicKeyStore; final myPrivate = pair.privateKey as RSAPrivateKeyStore; return AsymmetricKeyPair(myPublic, myPrivate); } SecureRandom getSecureRandom() { final secureRandom = SecureRandom('Fortuna')..seed(KeyParameter(encrypt.SecureRandom(32).bytes)); return secureRandom; } Future> getRSAKeyPair(String username) async { final _privateKey = 'e2ee chat private key of $username'; final _publicKey = 'e2ee chat public key of $username'; try { final privateKey = await RSAPrivateKeyStore.load(_privateKey); final publicKey = await RSAPublicKeyStore.load(_publicKey); if (privateKey != null && publicKey != null) { return AsymmetricKeyPair(publicKey, privateKey); } } catch (e) { debug('get rsa Public key failed: $e'); } final pair = generateRSAKeyPair(); pair.publicKey.save(_publicKey); pair.privateKey.save(_privateKey); await Api().addPublicKey(jsonEncode(pair.publicKey.toJson())); return pair; }