問題描述
我正在開發一個應用程序,該應用程序需要在 secp256r1
(NIST P-256、P-256、prime256v1)公鑰的幫助下驗證 SHA256withECDSA
簽名.p>
公鑰由不同的應用程序在較早的某個時間點生成,并以十六進制編碼存儲在我的數據庫中.這里的十六進制字符串的格式等同于 OpenSSL 在對文件 x.pem
調用 openssl ec -in x.pem -noout -text
時生成的十六進制字符串之前由 openssl ecparam -genkey -name secp256r1 -out x.pem
生成.消息和簽名是從不同的應用程序接收的.考慮以下測試數據:
//存儲在數據庫中byte[] pubKey = DatatypeConverter.parseHexBinary("049a55ad1e210cd113457ccd3465b930c9e7ade5e760ef64b63142dad43a308ed08e2d85632e8ff0322d3c7fda14409eafdc4c5b8ee0882fe885c92e//從其他應用程序接收字節[]消息= DatatypeConverter.parseHexBinary( 54686973206973206a75737420736f6d6520706f696e746c6573732064756d6d7920737472696e672e205468616e6b7320616e7977617920666f722074616b696e67207468652074696d6520746f206465636f6465206974203b2d29");字節[]簽名= DatatypeConverter.parseHexBinary( 304402205fef461a4714a18a5ca6dce6d5ab8604f09f3899313a28ab430eb9860f8be9d602203c8d36446be85383af3f2e8630f40c4172543322b5e8973e03fff2309755e654");
現在這個應該是一個有效的簽名.
我的目標是使用 Java 和/或 Bouncycastle 加密 API 驗證消息上的簽名.我為此創建了一個方法 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 事實 = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());return fact.generatePublic(new X509EncodedKeySpec(pubKey));}
但這會引發 java.security.spec.InvalidKeySpecException
(DER 長度超過 4 個字節:26).我該怎么做才能解析這個?
Bouncy Castle 橢圓曲線密鑰對生成和密鑰工廠示例代碼讓我非常接近.
一旦我設法為 secp256r1
/NIST P-256
/P-256
/創建了 ECDSA 密鑰工廠和曲線規范prime256v1
曲線 我能夠使用 ECPointUtil.decodePoint
來獲得曲線點.然后我可以生成一個公鑰規范,使我能夠生成這樣的公鑰:
private PublicKey getPublicKeyFromBytes(byte[] pubKey) throws NoSuchAlgorithmException, InvalidKeySpecException {ECNamedCurveParameterSpec 規范 = ECNamedCurveTable.getParameterSpec("prime256v1");KeyFactory kf = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());ECNamedCurveSpec params = new ECNamedCurveSpec("prime256v1", spec.getCurve(), spec.getG(), spec.getN());ECPoint 點 = 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;
}
這篇關于如何從 EC 公鑰字節中獲取 PublicKey 對象?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!