Closed phpcoinn closed 2 years ago
The ASN1 structure generated by "CryptoUtils.encodeEcPrivateKeyToPem()" looks good so far, compared to a private key generated with OpenSSL. I also tried to generate a CSR using the the generated EC private and public key. It works fine and the CSR was also accepted by the CA DigiCert. Due to the fact that they currently only support "prime256v1", I used this curve.
I would suggest :
Regards
Unfortunately I replicated these errors too. The package won't satisfy this online checker: https://8gwifi.org/ecsignverify.jsp
With secp256k1 curve and SHA-256 hash algorithm.
@kabaluyot Kann you please try it again with the current master branch? The public key algorithm was hardcoded set to prime256v1.
Yes I already tried this but the main issue as @phpcoinn mentioned was the wrong PEM generated especially for private key for secp256k1. Using this online tool, it doesnt match https://8gwifi.org/ecsignverify.jsp or you can use node crypto for comparison. @Ephenodrom
@kabaluyot Please try again with https://8gwifi.org/ecsignverify.jsp and the current master branch. I changed the PEM Header for the public key and now the tool at https://8gwifi.org/ecsignverify.jsp is working for me.
The EC private/public key has the same structure as the one generated with openssl. The only difference were :
Hi @Ephenodrom, thanks for the response. Did you happen to check if generated PEM in this package for signatures works well with whats in https://8gwifi.org/ecsignverify.jsp ?
Actually I applied the changes that you added to the PR that I created, but upon checking, looks like the PEM for private key is incorrectly encoded. Hence when trying and verifying signatures generated from Dart to the https://8gwifi.org/ecsignverify.jsp, it wont match.
Also if we can support signature in base64. I got this implementation from https://github.com/Ephenodrom/Dart-Basic-Utils/issues/57#issuecomment-991369507 .. What do you think?
/// Convert ECSignature [signature] to base64 string
/// This is mainly used for passing signature as string via request/response use cases
static String ecSignatureToBase64(ECSignature signature) {
var rUint8ListV2 = MathUtils.encodeBigInt(signature.r);
var sUint8ListV2 = MathUtils.encodeBigInt(signature.s);
var bbV2 = BytesBuilder();
bbV2.add(rUint8ListV2);
bbV2.add(sUint8ListV2);
return base64.encode(bbV2.toBytes());
}
@kabaluyot As I sad, with the latest commit, I was able to generate a EC keypair that can be used within the tool https://8gwifi.org/ecsignverify.jsp.
This included :
According the ecSignatureToBase64() method. This looks good, so please implement it and do not forget to add some unit tests. You can use the results from https://8gwifi.org/ecsignverify.jsp for the unit test to verify it.
So I tried implementing ecSignatureToBase64() with the latest master. Here are the steps I took:
// generate key pairs
var ec = CryptoUtils.generateEcKeyPair(curve: "secp256k1");
var privKey = ec.privateKey as ECPrivateKey;
var pubKey = ec.publicKey as ECPublicKey;
// convert to pem
var privKeyPem = CryptoUtils.encodeEcPrivateKeyToPem(privKey);
var pubKeyPem = CryptoUtils.encodeEcPublicKeyToPem(pubKey);
print('PrivKey PEM:\n$privKeyPem');
print('PubKey PEM:\n$pubKeyPem');
// convert pem to base64
var pubKeyBase64 = base64Encode(pubKeyPem.codeUnits);
print('PubKey base64: $pubKeyBase64');
// decode keys from pem
var decodedPrivKey = CryptoUtils.ecPrivateKeyFromPem(privKeyPem);
var decodedPubKey = CryptoUtils.ecPublicKeyFromPem(pubKeyPem);
// sign message
var message = Uint8List.fromList("Hello world!".codeUnits);
var signature = CryptoUtils.ecSign(decodedPrivKey, message,
algorithmName: 'SHA-256/ECDSA'); // can be SHA-256/ECDSA or other
var encodedSignature = CryptoUtils.ecSignatureToBase64(signature);
print('Signature in base64: $encodedSignature');
// verify message using ECSignature
var isVerifiedByECSignature = CryptoUtils.ecVerify(
decodedPubKey, message, signature,
algorithm: 'SHA-256/ECDSA');
print('ECSignature verification result: $isVerifiedByECSignature');
With the ff PEM pairs and result:
PrivKey PEM:
-----BEGIN EC PRIVATE KEY-----
MHUCAQEEIQCNeTXcKDOh232Nh4/wXDYbAN4a/7zZt4kcIjTd+Fy5aKAHBgUrgQQA
CqFEA0IABHm+Zn753LusVaBilc6HCwcCm/zbLc4o2VnygVsW+BeYSDradyajxGVd
pPv8DhEIqP0XtEimhVQZnEfQj/sQ1Lg=
-----END EC PRIVATE KEY-----
PubKey PEM:
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEL1xolif+76OIrvhEf8yL5m93ulxbha4M
aovLQr38tZ5yEOkM9acw+NOf9mkrfspYDFoRs5vjON4Cbjsn3DlIfg==
-----END PUBLIC KEY-----
PubKey base64: LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZZd0VBWUhLb1pJemowQ0FRWUZLNEVFQUFvRFFnQUVMMXhvbGlmKzc2T0lydmhFZjh5TDVtOTN1bHhiaGE0TQphb3ZMUXIzOHRaNXlFT2tNOWFjdytOT2Y5bWtyZnNwWURGb1JzNXZqT040Q2Jqc24zRGxJZmc9PQotLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0=
Signature in base64: LgDzj/gbIreZhLWSkRUgrXuL3YiaEd+vAKFjdPtYqT3dKokDxLGL04z7xfog5qLpWOTxH34/0jC2eUN6caXpKQ==
ECSignature verification result: true
true
I always get this error
@Ephenodrom
@kabaluyot Please take a look at my commits. I found out that the signature is indeed an ASN1 structure, so I made some changees to the ecSignatureToBase64() method. I also added a ecSignatureFromBase64() method. It should work now as expected.
@kabaluyot I think with the current commits we can close this issue and #57. Can you confirm this ? After that you can complete your PR and then I will merge and upload a new version on pub.dev.
Ok will verify the commits you pushed in master
@Ephenodrom I can confirm now that the signature is verified correctly with external tool:
For verify and example, here is the PR: https://github.com/Ephenodrom/Dart-Basic-Utils/pull/72
This can be considered as closed and fixed with the upcoming release. The package can now generate a DER encoded valid signature.
Hi, I am using your lib to implement crypto functions in my project, ECDSA key pair for secp256k1 curve.
But generated pem string is not correct, when I try to import it with php or nodejs code.
I checked code and found this part confusing:
https://github.com/Ephenodrom/Dart-Basic-Utils/blob/dcb0dcd12235d6e4fdeef7dfcfbd1fc34379fb23/lib/src/CryptoUtils.dart#L591
I think this is wrong because here is encoding of curve parameters, I think there need to be publicKey points x, y.
But that is not all. I am beginner in Dart, so I can not easy understand code. I think there are also some errors in further encoding of pem, and also added padding ASN1BitString.
Because there is no any other alternative for this, I will try my best to find out and help in solving this issue.