Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从EC公钥字节中获取公钥对象?_Java_Cryptography_Bouncycastle - Fatal编程技术网

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

Java 如何从EC公钥字节中获取公钥对象?,java,cryptography,bouncycastle,Java,Cryptography,Bouncycastle,我正在开发一个应用程序,需要借助于secp256r1(NIST p-256,p-256,prime256v1)公钥,使用ECDSA验证SHA256签名 公钥由不同的应用程序在较早的时间点生成,并以十六进制编码存储在我的数据库中。这里的十六进制字符串的格式相当于OpenSSL在调用文件x.pem上的OpenSSL ec-in x.pem-noout-text时生成的十六进制字符串OpenSSL,该文件先前由OpenSSL ecparam-genkey-name secp256r1-out x.pe

我正在开发一个应用程序,需要借助于
secp256r1
(NIST p-256,p-256,prime256v1)公钥,使用ECDSA验证
SHA256
签名

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

//存储在数据库中
byte[]pubKey=DatatypeConverter.parseHexBinary(“049a55ad1e210cd113457ccd3465b930c9e7ade5e760ef64b63142dad43a308ed08e2d85632e8ff0322d3c7fda14409eafdc4c5b8ee0882fe885c92e3789c36a7a”);
//从其他申请中收到
byte[]message=DatatypeConverter.parseHexBinary(“54686973206973206A75737420736F6D6520706F696E746C6573732064756D6D6D6D679207474672696E672E205468616E6B7320616E7977617920666F722074616E67272746652074696D65520746F20656F6465206974203B2D29”);
byte[]signature=DatatypeConverter.parseHexBinary(“304402205FEF461A4714A18A5CA6DCE6D5AB8604F09F3899313A28AB430EB9860F8BE9D602203C8D36446BE85383AF3E8630F40C417253322B5E8973E03FFF230975E654”);
现在这应该是一个有效的签名

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

私有静态布尔isValidSignature(字节[]公钥,字节[]消息,
字节[]签名)引发NoSuchAlgorithmException、NoSuchProviderException、InvalidKeyException、SignatureException、InvalidKeySpecException{
Signature ecdsaVerify=Signature.getInstance(“SHA256withECDSA”,new BouncyCastleProvider());
初始化验证(getPublicKeyFromHex(pubKey));
ecdsaVerify.update(消息);
返回ecdsaVerify.verify(签名);
}
我已尝试提取公钥:

KeyFactory.generatePublic:

private static PublicKey getPublicKeyFromHex(字节[]PublicKey)抛出NoSuchAlgorithmException、NoSuchProviderException、InvalidKeySpecException{
KeyFactory事实=KeyFactory.getInstance(“ECDSA”,新的BouncyCastleProvider());
返回事实.generatePublic(新的X509EncodedKeySpec(pubKey));
}
但这会抛出一个
java.security.spec.InvalidKeySpecException
(DER长度超过4字节:26)。 我能做些什么来解析它呢?

这让我非常接近

一旦我为
secp256r1
/
NIST p-256
/
p-256
/
prime256v1
曲线创建了ECDSA密钥工厂和曲线规范,我就能够使用
ECPointUtil.decodePoint
获得曲线点。然后,我可以生成一个公钥规范,使我能够生成这样的公钥:

private PublicKey getPublicKeyFromBytes(byte[]pubKey)抛出NoSuchAlgorithmException、InvalidKeySpecException{
ECNamedCurveParameterSpec=ECNamedCurveTable.getParameterSpec(“prime256v1”);
KeyFactory kf=KeyFactory.getInstance(“ECDSA”,新的BouncyCastleProvider());
ECNamedCurveSpec参数=新的ECNamedCurveSpec(“prime256v1”,spec.getCurve(),spec.getG(),spec.getN());
ECPoint point=ECPointUtil.decodePoint(params.getCurve(),pubKey);
ECPublicKeySpec pubKeySpec=新的ECPublicKeySpec(点,参数);
ECPublicKey pk=(ECPublicKey)kf.generatePublic(pubKeySpec);
返回主键;
}

只是为了在复制代码时保证正确性<代码>-nooutOpenSSL的选项拼写错误。谢谢,我正试图使用便携式bouncy castle来实现这一点,有什么想法吗?我失败了,因为android.mono中没有ECPointUtil