Closed Goddchen closed 4 years ago
Hi! Thanks for answering so quickly!
Unfortunately I don't get what you want to tell me with the link :/ Do you mean the "ECDSA is using deterministic k value generation as per RFC6979." part? Does it mean it is correct that I get deterministic signatures even with "p256"? If so, then why won't neither openssl, nor Java validate the signature? Both say it is invalid.
Yeah, the signatures are going to be the same for the same input data and private key.
Are you feeding hex string as an input to OpenSSL too? As a blind guess, I think .digest('hex')
might be a cuplrit. Could you try replacing it with just .digest()
?
In any case, it would help a lot if you'd post both:
Hi!
I just checked and it doesn't matter if I supply the hash from .digest('hex')
or from .digest()
. The generated signature is the same.
I don't have the openssl commands at hand right now but I have the Kotlin code:
val pemEncodedPublicKey = "..."
val r = BigInteger("16623944143491971676463174827292691248276097906054754250778903209279348118")
val s = BigInteger("8915207623119386215103726274096406162374916832888856290823602997291992632846")
val msg = "{1234 0 0 0 0.00 0.00 0.00 0.00 0.00}"
val publicKey = KeyFactory.getInstance("ECDSA", BouncyCastleProvider())
.generatePublic(X509EncodedKeySpec(PemReader(StringReader(pemEncodedPublicKey)).readPemObject().content))
val signature = Signature.getInstance("SHA256withECDSA", BouncyCastleProvider())
signature.initVerify(publicKey)
signature.update(msg.toByteArray())
val isValid = signature.verify(DERSequence(ASN1EncodableVector().apply {
add(ASN1Integer(r))
add(ASN1Integer(s))
}).getEncoded(ASN1Encoding.DER))
Assertions.assertThat(isValid).isTrue()
And this is my full code of how I create the signature with elliptic:
var pemPrivateKey = PrivateKey.fromPEM(pemEncodedPrivateKey)
var privateKey = ec.keyFromPrivate(pemPrivateKey.keyRaw)
var msgHash = shajs("sha256").update(createMeterUpdateString(meterUpdate)).digest()
var signature = privateKey.sign(msgHash)
Here's what I do in openssl:
First I export the signature from elliptic with signature.toDER("hex")
.
Then I convert it to binary with echo "3045022100aa8986096d7e915677892f95be506ff6e0e343da3d9f1694f1d3ab75b21a761602205bb4334cedb549dbce4c094d19a88931f80786a467baefb2e2c0b98edb9213a5" | xxd -r -p > signature.bin
.
Then I try to verify it with: openssl dgst -verify pub.pem -hex -signature signature.bin message
and I get Verification Failure
.
Might it be possible that I'm reading the private key wrong? This is my private key variable:
var pemEncodedPrivateKey = "-----BEGIN PRIVATE KEY-----\nMIGEAgE...............ZUQAxwUrukh\n-----END PRIVATE KEY-----"
I found my issue after a lot of debugging. It was indeed the format of the private key. I am now passing in the raw elliptic curve coordinate formatted as hex and now it is working!
Hi have an issue with using this library. I am creating P-256 signatures. I always fail to verify my signature with other tools like openssl or in my Java/Kotlin code. So I ran some tests... When I generate signatures with openssl or Java (BouncyCastle) over the same input data, I always get a different signare r and s. Which is consistent with what I expected since P-256 is non-deterministic.
But when I create multiple signatures over the same data with this library. I always end up with the same r and s.
Any ideas what I might be doing wrong?
I end up with 3 identical signatures.