如何从EC公钥字节获取PublicKey对象? [英] How can I get a PublicKey object from EC public key bytes?

查看:3623
本文介绍了如何从EC公钥字节获取PublicKey对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个应用程序,需要借助于 secp256r1 (NIST P-256)验证 SHA256withECDSA ,P-256,prime256v1)公共密钥。

I am developing an application that needs to validate SHA256withECDSAsignatures with the help of secp256r1 (NIST P-256, P-256, prime256v1) public keys.

公共密钥由不同的应用程序在较早的时间点生成,并以十六进制编码存储在我的数据库中。这里十六进制字符串的格式等价于当在文件上调用 openssl ec -in x.pem -noout -text 时,OpenSSL会生成的十六进制字符串 x.pem ,它之前由 openssl ecparam -genkey -name secp256r1 -out x.pem 生成。
消息和签名从不同的应用程序接收。
考虑以下测试数据:

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.

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

My objective is to validate the signature over the message using the Java and/or Bouncycastle crypto API. I have created a method isValidSignaturefor 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));
}

但这会抛出一个 java.security.spec。 InvalidKeySpecException (DER长度超过4个字节:26)。
我可以做什么来解析这个?

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.

一旦我设法为 secp256r1 / NIST创建一个ECDSA密钥工厂和曲线规范曲线P-256 / P-256 / prime256v1 c $ c> ECPointUtil.decodePoint 以获取曲线点。然后我可以生成一个公共密钥规范,使我能够生成如下的公共密钥:

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对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆