我怎样才能摆脱EC公钥字节的公钥对象?我怎样才能摆脱EC公钥字节的公钥对象?(How can I g

2019-05-12 04:52发布

我正在开发一个需要验证的应用程序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);
}

我曾尝试提取公钥:

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)。 我能做些什么来分析呢?

Answer 1:

在椭圆曲线密钥对生成和密钥工厂充气城堡的示例代码让我相当接近。

有一次,我成功地创建一个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;
}


文章来源: How can I get a PublicKey object from EC public key bytes?