如何从EC公钥字节中获取PublicKey对象?

我正在开发一个需要SHA256withECDSA借助secp256r1(NIST

P-256,P-256,prime256v1)公钥来验证签名的应用程序。

公钥是由其他应用程序在较早的时间点生成的,并以十六进制编码存储在我的数据库中。十六进制字符串的格式等效于OpenSSL在调用以前由生成openssl ec

-in x.pem -noout

-text的文件时将生成的十六进制字符串。消息和签名是从其他应用程序接收的。考虑以下测试数据:x.pem``openssl ecparam

-genkey -name secp256r1 -out x.pem

// Stored in Database

byte[] pubKey = DatatypeConverter.parseHexBinary("049a55ad1e210cd113457ccd3465b930c9e7ade5e760ef64b63142dad43a308ed08e2d85632e8ff0322d3c7fda14409eafdc4c5b8ee0882fe885c92e3789c36a7a");

// Received from Other Application

byte[] message = DatatypeConverter.parseHexBinary("54686973206973206a75737420736f6d6520706f696e746c6573732064756d6d7920737472696e672e205468616e6b7320616e7977617920666f722074616b696e67207468652074696d6520746f206465636f6465206974203b2d29");

byte[] signature = DatatypeConverter.parseHexBinary("304402205fef461a4714a18a5ca6dce6d5ab8604f09f3899313a28ab430eb9860f8be9d602203c8d36446be85383af3f2e8630f40c4172543322b5e8973e03fff2309755e654");

现在,这 应该 是有效的签名。

我的目标是使用Java和/或Bouncycastle加密API验证消息上的签名。我isValidSignature为此创建了一个方法:

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);

}

我试图提取公钥:

private static PublicKey getPublicKeyFromHex(byte[] pubKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException {

KeyFactory fact = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());

return fact.generatePublic(new X509EncodedKeySpec(pubKey));

}

但这会引发一个java.security.spec.InvalidKeySpecException(DER长度超过4个字节:26)。我该怎么做才能解析?

回答:

椭圆曲线键对Generation和键工厂上的Bouncy

Castle示例代码使我非常接近。

一旦我成功创建了ECDSA密钥工厂和secp256r1/ NIST P-256/ P-256/

prime256v1曲线的曲线规范,便可以ECPointUtil.decodePoint用来获取曲线点。然后,我可以生成一个公共密钥规范,该规范使我能够生成这样的公共密钥:

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对象? 的全部内容, 来源链接: utcz.com/qa/423218.html

回到顶部