I have a public key, and its corresponded signature, R, S values generated by nodejs (v20.14.0) with the function as below
const { privateKey, publicKey } = crypto.generateKeyPairSync('ec', {
namedCurve: 'P-256', //'secp256k1', // invalid 'secp256r1',
publicKeyEncoding: { type: 'spki', format: 'der' }
});
const sign = crypto.createSign('SHA256');
const message = 'my message';
sign.update(message);
sign.end();
const signature = sign.sign(privateKey);
const RLength = parseInt(signature.toString('hex', 3, 4), 16);
const R = signature.subarray(4, 4+RLength);
const S = signature.subarray(4+RLength+2, signature.length);
A sample result:
- public key:
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEL+RfybPlDY/+KMwY3ROpD4aSgtJFxnPOraWQpJkMJ0Ovj4rkrOSMPj+5rhE3jCJNYOV35TIGomJSxI65shfKug==. - signature:
MEUCIQD+SjM+JD2u91p2Fy8UKtkMqXCkSPaCCIDFBaqzVbDA6QIgU5pGg8qnt7iWHpL9Anw5uxLXTH64gj9V9o0HjEmsBWo= - R:
AP5KMz4kPa73WnYXLxQq2QypcKRI9oIIgMUFqrNVsMDp - S:
U5pGg8qnt7iWHpL9Anw5uxLXTH64gj9V9o0HjEmsBWo=
These values will be passed to my java program (java 11) for verifying. The java program is
String pkey = "MFkwEw...Kug=="; // the entire base64 string above
byte[] publicKey = Base64.getDecoder().decode(pkey);
X9ECParameters curve = NISTNamedCurves.getByName("P-256"); //"secp256k1"
ECDomainParameters domain = new ECDomainParameters(curve.getCurve(), curve.getG(), curve.getN(), curve.getH());
ECDSASigner signer = new ECDSASigner(); // I use bouncy castle 1.78
signer.init (
false,
new ECPublicKeyParameters(
curve.getCurve().decodePoint(publicKey), // the place where exception is thrown
domain
)
);
signer.verifySignature(
message,
new BigInteger(Base64.getDecoder().decode(R)),
new BigInteger(Base64.getDecoder().decode(S))
);
However, the java code throws the error java.lang.IllegalArgumentException: Invalid point encoding 0x30.
Why the NISTNamedCurves can't decode the base64 string? I am completely new to cryptography, so I search with the exception Invalid point encoding 0x30. Some threads like [1] comes out, but I can't figure out why.
I appreciate any advice. Many thanks.
Edit: Valid test data:
public key (SPKI): MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/UREdRdAbtwg/HeUhb8B2rICVjIT7ZtxloBVNrBV0jiMCOLmVs8gm0LE7oWlPfBToaWsbfp2sCCR5EhhalGeHQ==
signature (ASN.1/DER): MEYCIQDLeC2T8ZIlruOw3Km0THK8yxcMPS5ufOHqus3Y/vyYMgIhAKgoAIV50yXYGIARdNE4bEt+eaujKFwX2cX6pf/y681p
R: AMt4LZPxkiWu47DcqbRMcrzLFww9Lm584eq6zdj+/Jgy
S: AKgoAIV50yXYGIARdNE4bEt+eaujKFwX2cX6pf/y681p
message: my message
message,publicKey,signature) are inconsistent, even with NodeJS they cannot be verified: jdoodle.com/ia/14H1. Please post consistent data.decodePoint()requires the uncompressed/compressed public key), which is the cause of the error message. In addition, the hashing is missing (ECDSASigner#verifySignature()does not hash implicitly).RandS, i.e.signaturecan be verified directly on the Java side.MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/UREdRdAbtwg/HeUhb8B2rICVjIT7ZtxloBVNrBV0jiMCOLmVs8gm0LE7oWlPfBToaWsbfp2sCCR5EhhalGeHQ==, sign:MEYCIQDLeC2T8ZIlruOw3Km0THK8yxcMPS5ufOHqus3Y/vyYMgIhAKgoAIV50yXYGIARdNE4bEt+eaujKFwX2cX6pf/y681p, R:AMt4LZPxkiWu47DcqbRMcrzLFww9Lm584eq6zdj+/Jgy, S:AKgoAIV50yXYGIARdNE4bEt+eaujKFwX2cX6pf/y681p