message.dart 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import 'dart:convert';
  2. import 'package:crypto/crypto.dart';
  3. import 'package:e2ee_chat/common/cipher.dart';
  4. import 'package:json_annotation/json_annotation.dart';
  5. import 'package:dash_chat/dash_chat.dart';
  6. import 'package:encrypt/encrypt.dart';
  7. import 'package:pointycastle/asymmetric/api.dart';
  8. import 'package:crypto/crypto.dart';
  9. part 'message.g.dart';
  10. @JsonSerializable()
  11. class Message {
  12. Message(
  13. {required this.from,
  14. required this.to,
  15. required this.encKey64,
  16. required this.cipherText64,
  17. required this.publicKeyJson,
  18. required this.sign64,
  19. required this.iv64});
  20. factory Message.fromJson(Map<String, dynamic> json) => _$MessageFromJson(json);
  21. Map<String, dynamic> toJson() => _$MessageToJson(this);
  22. String from;
  23. String to;
  24. String encKey64;
  25. String cipherText64;
  26. String publicKeyJson;
  27. String sign64;
  28. String iv64;
  29. static Future<Message> encrypt(String from, String to, String plaintext, RSAPublicKeyStore publicKey) async {
  30. final key = Key.fromSecureRandom(1024); // aes 密钥
  31. final keyEnc = Encrypter(RSA(publicKey: publicKey));
  32. final encKey = keyEnc.encrypt(key.base64); // rsa 加密 aes 密钥
  33. final iv = IV.fromLength(64);
  34. final textEnc = Encrypter(AES(key));
  35. final cipherText = textEnc.encrypt(plaintext, iv: iv); // 密文
  36. final pair = await getRSAKeyPair(from);
  37. final signEnc = Encrypter(RSA(privateKey: pair.privateKey));
  38. final digest = sha512.convert(utf8.encode(plaintext)); // hash
  39. final sign = signEnc.encrypt(digest.toString()); // hex 签名
  40. return Message(
  41. from: from,
  42. to: to,
  43. encKey64: encKey.base64,
  44. cipherText64: cipherText.base64,
  45. publicKeyJson: jsonEncode(pair.publicKey.toJson()),
  46. sign64: sign.base64,
  47. iv64: iv.base64);
  48. }
  49. Future<ChatMessage?> get chatMessage async {
  50. ChatMessage? _message;
  51. final pair = await getRSAKeyPair(from);
  52. final keyEnc = Encrypter(RSA(privateKey: pair.privateKey));
  53. final keyBase64 = keyEnc.decrypt64(encKey64);
  54. final key = Key.fromBase64(keyBase64); // 获取key
  55. final iv = IV.fromBase64(iv64);
  56. final textEnc = Encrypter(AES(key));
  57. final plaintext = textEnc.decrypt64(cipherText64, iv: iv);
  58. final publicKey = RSAPublicKeyStore.fromJson(jsonDecode(publicKeyJson));
  59. final signEnc = Encrypter(RSA(publicKey: publicKey));
  60. final digestHex = signEnc.decrypt64(sign64);
  61. final digest = sha512.convert(utf8.encode(plaintext));
  62. if (digest.toString() == digestHex) {
  63. _message = ChatMessage.fromJson(jsonDecode(plaintext));
  64. }
  65. return _message;
  66. }
  67. }
  68. /*
  69. class GroupMessage {
  70. int id = 0;
  71. String plaintext = "";
  72. final user = ToOne<User>();
  73. final group = ToOne<Group>();
  74. @Transient()
  75. ChatMessage get chatMessage => ChatMessage.fromJson(jsonDecode(plaintext));
  76. }
  77. */