import 'dart:convert'; import 'package:crypto/crypto.dart'; import 'package:e2ee_chat/common/cipher.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:dash_chat/dash_chat.dart'; import 'package:encrypt/encrypt.dart'; import 'package:pointycastle/asymmetric/api.dart'; import 'package:crypto/crypto.dart'; part 'message.g.dart'; @JsonSerializable() class Message { Message( {required this.from, required this.to, required this.encKey64, required this.cipherText64, required this.publicKeyJson, required this.sign64, required this.iv64}); factory Message.fromJson(Map json) => _$MessageFromJson(json); Map toJson() => _$MessageToJson(this); String from; String to; String encKey64; String cipherText64; String publicKeyJson; String sign64; String iv64; static Future encrypt(String from, String to, String plaintext, RSAPublicKeyStore publicKey) async { final key = Key.fromSecureRandom(1024); // aes 密钥 final keyEnc = Encrypter(RSA(publicKey: publicKey)); final encKey = keyEnc.encrypt(key.base64); // rsa 加密 aes 密钥 final iv = IV.fromLength(64); final textEnc = Encrypter(AES(key)); final cipherText = textEnc.encrypt(plaintext, iv: iv); // 密文 final pair = await getRSAKeyPair(from); final signEnc = Encrypter(RSA(privateKey: pair.privateKey)); final digest = sha512.convert(utf8.encode(plaintext)); // hash final sign = signEnc.encrypt(digest.toString()); // hex 签名 return Message( from: from, to: to, encKey64: encKey.base64, cipherText64: cipherText.base64, publicKeyJson: jsonEncode(pair.publicKey.toJson()), sign64: sign.base64, iv64: iv.base64); } Future get chatMessage async { ChatMessage? _message; final pair = await getRSAKeyPair(from); final keyEnc = Encrypter(RSA(privateKey: pair.privateKey)); final keyBase64 = keyEnc.decrypt64(encKey64); final key = Key.fromBase64(keyBase64); // 获取key final iv = IV.fromBase64(iv64); final textEnc = Encrypter(AES(key)); final plaintext = textEnc.decrypt64(cipherText64, iv: iv); final publicKey = RSAPublicKeyStore.fromJson(jsonDecode(publicKeyJson)); final signEnc = Encrypter(RSA(publicKey: publicKey)); final digestHex = signEnc.decrypt64(sign64); final digest = sha512.convert(utf8.encode(plaintext)); if (digest.toString() == digestHex) { _message = ChatMessage.fromJson(jsonDecode(plaintext)); } return _message; } } /* class GroupMessage { int id = 0; String plaintext = ""; final user = ToOne(); final group = ToOne(); @Transient() ChatMessage get chatMessage => ChatMessage.fromJson(jsonDecode(plaintext)); } */