From 422c8bf88d28f53cf7fe061f6f02c420aa1e5055 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Sat, 30 Oct 2021 21:37:28 +0100 Subject: [PATCH] use PSS signature verification --- packages/simplexmq/lib/src/crypto.dart | 76 +++++++++---------- packages/simplexmq/lib/src/transport.dart | 1 + .../simplexmq_io/test/transport_test.dart | 4 +- 3 files changed, 39 insertions(+), 42 deletions(-) diff --git a/packages/simplexmq/lib/src/crypto.dart b/packages/simplexmq/lib/src/crypto.dart index bc00093ef..0ce266dd0 100644 --- a/packages/simplexmq/lib/src/crypto.dart +++ b/packages/simplexmq/lib/src/crypto.dart @@ -10,8 +10,8 @@ import 'package:pointycastle/digests/sha256.dart'; import 'package:pointycastle/key_generators/api.dart'; import 'package:pointycastle/key_generators/rsa_key_generator.dart'; import 'package:pointycastle/random/fortuna_random.dart'; -import 'package:pointycastle/signers/rsa_signer.dart'; -import 'buffer.dart' show empty; +import 'package:pointycastle/signers/pss_signer.dart'; +import 'buffer.dart'; class AESKey { final Uint8List _key; @@ -25,19 +25,13 @@ class AESKey { Uint8List get bytes => _key; } -Uint8List randomIV() { - return pseudoRandomBytes(16); -} +Uint8List randomIV() => pseudoRandomBytes(16); -Uint8List secureRandomBytes(int len) { - return _randomBytes(len, Random.secure()); -} +Uint8List secureRandomBytes(int len) => _randomBytes(len, Random.secure()); final sessionSeed = Random.secure(); -Uint8List pseudoRandomBytes(int len) { - return _randomBytes(len, sessionSeed); -} +Uint8List pseudoRandomBytes(int len) => _randomBytes(len, sessionSeed); Uint8List _randomBytes(int len, Random seedSource) { final bytes = Uint8List(len); @@ -49,7 +43,11 @@ Uint8List _randomBytes(int len, Random seedSource) { final paddingByte = '#'.codeUnitAt(0); -Uint8List encryptAES(AESKey key, Uint8List iv, int padTo, Uint8List data) { +const int _macBytes = 16; +const int _macBits = _macBytes * 8; + +Uint8List encryptAES(AESKey key, Uint8List iv, int blockSize, Uint8List data) { + final padTo = blockSize - _macBytes; if (data.length >= padTo) throw ArgumentError('large message'); final padded = Uint8List(padTo); padded.setAll(0, data); @@ -57,18 +55,16 @@ Uint8List encryptAES(AESKey key, Uint8List iv, int padTo, Uint8List data) { return _makeGCMCipher(key, iv, true).process(padded); } -Uint8List decryptAES(AESKey key, Uint8List iv, Uint8List encryptedAndTag) { - return _makeGCMCipher(key, iv, false).process(encryptedAndTag); -} +Uint8List decryptAES(AESKey key, Uint8List iv, Uint8List encryptedAndTag) => + _makeGCMCipher(key, iv, false).process(encryptedAndTag); -GCMBlockCipher _makeGCMCipher(AESKey key, Uint8List iv, bool encrypt) { - return GCMBlockCipher(AESFastEngine()) - ..init(encrypt, AEADParameters(KeyParameter(key._key), 128, iv, empty)); -} +GCMBlockCipher _makeGCMCipher(AESKey key, Uint8List iv, bool encrypt) => + GCMBlockCipher(AESFastEngine()) + ..init( + encrypt, AEADParameters(KeyParameter(key._key), _macBits, iv, empty)); -FortunaRandom _secureFortunaRandom() { - return FortunaRandom()..seed(KeyParameter(secureRandomBytes(32))); -} +FortunaRandom _secureFortunaRandom() => + FortunaRandom()..seed(KeyParameter(secureRandomBytes(32))); AsymmetricKeyPair generateRSAkeyPair( [int bitLength = 2048]) { @@ -81,30 +77,30 @@ AsymmetricKeyPair generateRSAkeyPair( pair.publicKey as RSAPublicKey, pair.privateKey as RSAPrivateKey); } -Uint8List encryptOAEP(RSAPublicKey key, Uint8List data) { - final oaep = OAEPEncoding.withSHA256(RSAEngine()) - ..init(true, PublicKeyParameter(key)); - return oaep.process(data); -} +Uint8List encryptOAEP(RSAPublicKey key, Uint8List data) => + _oaep(true, PublicKeyParameter(key)).process(data); -Uint8List decryptOAEP(RSAPrivateKey key, Uint8List data) { - final oaep = OAEPEncoding.withSHA256(RSAEngine()) - ..init(false, PrivateKeyParameter(key)); - return oaep.process(data); -} +Uint8List decryptOAEP(RSAPrivateKey key, Uint8List data) => + _oaep(false, PrivateKeyParameter(key)).process(data); -Uint8List signPSS(RSAPrivateKey privateKey, Uint8List data) { - final signer = RSASigner(SHA256Digest(), '0609608648016503040201') - ..init(true, PrivateKeyParameter(privateKey)); - return signer.generateSignature(data).bytes; -} +OAEPEncoding _oaep(bool encrypt, AsymmetricKeyParameter keyParam) => + OAEPEncoding.withSHA256(RSAEngine())..init(encrypt, keyParam); + +Uint8List signPSS(RSAPrivateKey privateKey, Uint8List data) => + _pss(true, PrivateKeyParameter(privateKey)) + .generateSignature(data) + .bytes; bool verifyPSS(RSAPublicKey publicKey, Uint8List data, Uint8List sig) { - final verifier = RSASigner(SHA256Digest(), '0609608648016503040201') - ..init(false, PublicKeyParameter(publicKey)); try { - return verifier.verifySignature(data, RSASignature(sig)); + return _pss(false, PublicKeyParameter(publicKey)) + .verifySignature(data, PSSSignature(sig)); } on ArgumentError { return false; } } + +PSSSigner _pss(bool sign, AsymmetricKeyParameter keyParam) => PSSSigner( + RSAEngine(), SHA256Digest(), SHA256Digest()) + ..init(sign, + ParametersWithSaltConfiguration(keyParam, _secureFortunaRandom(), 32)); diff --git a/packages/simplexmq/lib/src/transport.dart b/packages/simplexmq/lib/src/transport.dart index baf6cf9a4..ab8227e7b 100644 --- a/packages/simplexmq/lib/src/transport.dart +++ b/packages/simplexmq/lib/src/transport.dart @@ -291,6 +291,7 @@ class SMPTransportClient { Future _readEncrypted() async { final block = await _conn.read(blockSize); + print('encrypted received'); final iv = _nextIV(_rcvKey); return decryptAES(_rcvKey.aesKey, iv, block); } diff --git a/packages/simplexmq_io/test/transport_test.dart b/packages/simplexmq_io/test/transport_test.dart index 3b46e0edc..304499893 100644 --- a/packages/simplexmq_io/test/transport_test.dart +++ b/packages/simplexmq_io/test/transport_test.dart @@ -19,7 +19,7 @@ void main() { final conn1 = await SocketTransport.connect('localhost', 5223); final alice = await SMPTransportClient.connect(conn1, keyHash: keyHash); final aliceKeys = generateRSAkeyPair(); - final rcvKeyStr = encode64(encodeRsaPubKey(aliceKeys.publicKey)); + final rcvKeyBytes = encodeRsaPubKey(aliceKeys.publicKey); // final conn2 = await SocketTransport.connect('localhost', 5223); // final bob = await SMPTransportClient.connect(conn2, keyHash: keyHash); @@ -29,7 +29,7 @@ void main() { // print('we are here'); final resp = await alice.sendSMPCommand( - aliceKeys.privateKey, empty, NEW(rcvKeyStr)); + aliceKeys.privateKey, empty, NEW(rcvKeyBytes)); print(resp); }); // });