I‘m a rookie in PointyCastle,how can I generate ecc base64 key pairs with PointyCastle in dart
AsymmetricKeyPair<PublicKey, PrivateKey> generateKeyPair({curve = 'secp256r1'}) {
var param = curve == 'secp256r1' ? ECCurve_secp256r1() : ECCurve_secp256k1();
var keyParams = ECKeyGeneratorParameters(param);
var random = FortunaRandom();
random.seed(KeyParameter(_seed()));
var generator = ECKeyGenerator();
generator.init(ParametersWithRandom(keyParams, random));
return generator.generateKeyPair();
}
Uint8List _seed() {
var random = Random.secure();
var seed = List<int>.generate(32, (_) => random.nextInt(256));
return Uint8List.fromList(seed);
}
above I can generate a AsymmetricKeyPair object,how to get public base64 and private base64 like my already done js bundle
{"priKey":"CVK3r/UxdGCwQBjtn5vN/orUMxKf9E/1TlJzLkMz9t4=","pubKey":"BJH/mWJqgchGxXGA5/E79SsWRwVo3rpduBmD8FOs7UlKiK8PIvwrkCDvUcwhKdysW35OByPjoVcwFqg1NyumLKM="}
besides, at first I want to use my js bundle file in flutter android, but that would be very tough as I know
how to use js bundle in flutter android
I also need to make sign and verify function with ecdsa in sha256
Signer signer = new Signer('SHA-256/ECDSA');
// 签名,参数:私钥,明文
ECSignature sign(String privateKeyStr, String txt) {
SecureRandom random = _setRadom();
// how to convert a plain txt to kTestBytes
final Uint8List kTestBytes = new Uint8List.fromList([1, 2, 3]);
// if I pass in base64 privateKey str, is the radix 64?
ECPrivateKey privateKey = new ECPrivateKey(BigInt.parse(privateKeyStr, radix: 10), ecDomain);
PrivateKeyParameter signParams = new PrivateKeyParameter(privateKey);
signer.init(true, new ParametersWithRandom(signParams, random));
ECSignature signature = signer.generateSignature(kTestBytes) as ECSignature;
return signature;
}
// 验签
// 参数: 明文,签名,公钥
bool verify(txt, signature, publicKey) {
// how to make the txt to kTestBytes
var kTestBytes = txt
signer.init(false, new PublicKeyParameter(publicKey));
bool verify = signer.verifySignature(kTestBytes, signature);
// print(verify);
return verify;
}
// I don't know what this function actually do,as I know in other language ecdsa don;t need a random number.
SecureRandom _setRadom() {
List<int> key = [67, 3, 241, 75, 143, 78, 115, 99, 21, 242, 180, 43, 26, 7, 194, 20];
List<int> iv = [87, 117, 137, 182, 2, 199, 132, 230, 120, 12, 109, 177, 34, 197, 186, 206];
KeyParameter keyParam = new KeyParameter(new Uint8List.fromList(key));
ParametersWithIV<KeyParameter> paramsIV = new ParametersWithIV(keyParam, new Uint8List.fromList(iv));
SecureRandom random = new SecureRandom('AES/CTR/AUTO-SEED-PRNG')..seed(paramsIV);
return random;
}
Any place can I find sample codes, these functions were changed by some copies on the internet。and I got many confuses list in the comment
The EC keys are to be exported/imported as a Base64 encoded raw private key and as a Base64 encoded raw uncompressed public key.
First of all it can be stated that signing and verifying with the posted code works when a fresh key pair is generated:
I.e. in the following I will focus on the import/export of the keys. The raw keys are encapsulated in
ECPrivateKeyandECPublicKeyand can be exported and imported as follows:Here
dis the raw private key andxandyare the x and y coordinates of the raw public key.On the JavaScript side, the Base64 encoded raw private key is used and the Base64 encoded raw uncompressed key, where the uncompressed key is the concatenation
0x04 + <x> + <y>. So, for export and import, the following applies:Regarding the export, the Base64 encoded raw private and public key can be derived from
d,x, andyas follows:with
The size passed in
exportPublic()as 3rd parameter is the size of the order of the generator point (32 bytes for secp256r1). Ifxoryare smaller, they are each padded from the front with 0x00 values until the required length is reached.For the conversion from
BigInttoUint8Listand the concatenation I used theNanoHelpersclass from the NanoDart package for simplicity. Of course, other implementations can be used here as well.Regarding the import,
d,x, andycan be derived from the Base64 encoded raw private and public key as follows:with
Test
The posted key pair
can be imported and used for signing and verification as follows:
Edit: Regarding your comment:
sign()andverify()are the methods you posted, but according to the changes, the keys are now passed directly (instead of strings) and the actual message is applied (instead of[1,2,3]) usingutf8.encode()for UTF-8 encoding:As
_setRandom()I applied the implementation fromgenerateKeyPair()instead of your implementation (i.e. aFortunaRandom()based CSPRNG).