問題描述
我正在開發(fā)一個(gè)應(yīng)用程序,該應(yīng)用程序需要在 secp256r1
(NIST P-256、P-256、prime256v1)公鑰的幫助下驗(yàn)證 SHA256withECDSA
簽名.p>
公鑰由不同的應(yīng)用程序在較早的某個(gè)時(shí)間點(diǎn)生成,并以十六進(jìn)制編碼存儲(chǔ)在我的數(shù)據(jù)庫(kù)中.這里的十六進(jìn)制字符串的格式等同于 OpenSSL 在對(duì)文件 x.pem
調(diào)用 openssl ec -in x.pem -noout -text
時(shí)生成的十六進(jìn)制字符串之前由 openssl ecparam -genkey -name secp256r1 -out x.pem
生成.消息和簽名是從不同的應(yīng)用程序接收的.考慮以下測(cè)試數(shù)據(jù):
//存儲(chǔ)在數(shù)據(jù)庫(kù)中byte[] pubKey = DatatypeConverter.parseHexBinary("049a55ad1e210cd113457ccd3465b930c9e7ade5e760ef64b63142dad43a308ed08e2d85632e8ff0322d3c7fda14409eafdc4c5b8ee0882fe885c92e//從其他應(yīng)用程序接收字節(jié)[]消息= DatatypeConverter.parseHexBinary( 54686973206973206a75737420736f6d6520706f696e746c6573732064756d6d7920737472696e672e205468616e6b7320616e7977617920666f722074616b696e67207468652074696d6520746f206465636f6465206974203b2d29");字節(jié)[]簽名= DatatypeConverter.parseHexBinary( 304402205fef461a4714a18a5ca6dce6d5ab8604f09f3899313a28ab430eb9860f8be9d602203c8d36446be85383af3f2e8630f40c4172543322b5e8973e03fff2309755e654");
現(xiàn)在這個(gè)應(yīng)該是一個(gè)有效的簽名.
我的目標(biāo)是使用 Java 和/或 Bouncycastle 加密 API 驗(yàn)證消息上的簽名.我為此創(chuàng)建了一個(gè)方法 isValidSignature
:
private static boolean isValidSignature(byte[] pubKey, byte[] message,byte[] 簽名)拋出 NoSuchAlgorithmException、NoSuchProviderException、InvalidKeyException、SignatureException、InvalidKeySpecException {簽名 ecdsaVerify = Signature.getInstance("SHA256withECDSA", new BouncyCastleProvider());ecdsaVerify.initVerify(getPublicKeyFromHex(pubKey));ecdsaVerify.update(消息);返回 ecdsaVerify.verify(簽名);}
我已嘗試提取公鑰:
KeyFactory.generatePublic:
private static PublicKey getPublicKeyFromHex(byte[] pubKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException {KeyFactory 事實(shí) = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());return fact.generatePublic(new X509EncodedKeySpec(pubKey));}
但這會(huì)引發(fā) java.security.spec.InvalidKeySpecException
(DER 長(zhǎng)度超過 4 個(gè)字節(jié):26).我該怎么做才能解析這個(gè)?
Bouncy Castle 橢圓曲線密鑰對(duì)生成和密鑰工廠示例代碼讓我非常接近.
一旦我設(shè)法為 secp256r1
/NIST P-256
/P-256
/創(chuàng)建了 ECDSA 密鑰工廠和曲線規(guī)范prime256v1
曲線 我能夠使用 ECPointUtil.decodePoint
來(lái)獲得曲線點(diǎn).然后我可以生成一個(gè)公鑰規(guī)范,使我能夠生成這樣的公鑰:
private PublicKey getPublicKeyFromBytes(byte[] pubKey) throws NoSuchAlgorithmException, InvalidKeySpecException {ECNamedCurveParameterSpec 規(guī)范 = ECNamedCurveTable.getParameterSpec("prime256v1");KeyFactory kf = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());ECNamedCurveSpec params = new ECNamedCurveSpec("prime256v1", spec.getCurve(), spec.getG(), spec.getN());ECPoint 點(diǎn) = ECPointUtil.decodePoint(params.getCurve(), pubKey);ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, params);ECPublicKey pk = (ECPublicKey) kf.generatePublic(pubKeySpec);返回PK;}
I am developing an application that needs to validate SHA256withECDSA
signatures with the help of secp256r1
(NIST P-256, P-256, prime256v1) public keys.
The public keys are generated by a different application at some earlier point in time and stored in my database in hex encoding. The format of the hex string here is equivalent to the hex string OpenSSL would generate when calling openssl ec -in x.pem -noout -text
on a file x.pem
that has previously been generated by openssl ecparam -genkey -name secp256r1 -out x.pem
.
The message and signature are received from a different application.
Consider the following test data:
// Stored in Database
byte[] pubKey = DatatypeConverter.parseHexBinary("049a55ad1e210cd113457ccd3465b930c9e7ade5e760ef64b63142dad43a308ed08e2d85632e8ff0322d3c7fda14409eafdc4c5b8ee0882fe885c92e3789c36a7a");
// Received from Other Application
byte[] message = DatatypeConverter.parseHexBinary("54686973206973206a75737420736f6d6520706f696e746c6573732064756d6d7920737472696e672e205468616e6b7320616e7977617920666f722074616b696e67207468652074696d6520746f206465636f6465206974203b2d29");
byte[] signature = DatatypeConverter.parseHexBinary("304402205fef461a4714a18a5ca6dce6d5ab8604f09f3899313a28ab430eb9860f8be9d602203c8d36446be85383af3f2e8630f40c4172543322b5e8973e03fff2309755e654");
Now this should be a valid signature.
My objective is to validate the signature over the message using the Java and/or Bouncycastle crypto API. I have created a method isValidSignature
for that:
private static boolean isValidSignature(byte[] pubKey, byte[] message,
byte[] signature) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException, InvalidKeySpecException {
Signature ecdsaVerify = Signature.getInstance("SHA256withECDSA", new BouncyCastleProvider());
ecdsaVerify.initVerify(getPublicKeyFromHex(pubKey));
ecdsaVerify.update(message);
return ecdsaVerify.verify(signature);
}
I have tried to extract the public key:
KeyFactory.generatePublic:
private static PublicKey getPublicKeyFromHex(byte[] pubKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException {
KeyFactory fact = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());
return fact.generatePublic(new X509EncodedKeySpec(pubKey));
}
But this throws a java.security.spec.InvalidKeySpecException
(DER length more than 4 bytes: 26).
What can I do to parse this?
The Bouncy Castle example code on elliptic curve key pair Generation and key factories got me pretty close.
Once I managed to create a ECDSA key factory and a curve specification for the secp256r1
/NIST P-256
/P-256
/prime256v1
curve I was able to use ECPointUtil.decodePoint
to obtain a curve point. I could then generate a public key specification that enabled me to generate a public key like this:
private PublicKey getPublicKeyFromBytes(byte[] pubKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1");
KeyFactory kf = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());
ECNamedCurveSpec params = new ECNamedCurveSpec("prime256v1", spec.getCurve(), spec.getG(), spec.getN());
ECPoint point = ECPointUtil.decodePoint(params.getCurve(), pubKey);
ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, params);
ECPublicKey pk = (ECPublicKey) kf.generatePublic(pubKeySpec);
return pk;
}
這篇關(guān)于如何從 EC 公鑰字節(jié)中獲取 PublicKey 對(duì)象?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!