当前位置: 首页 > 知识库问答 >
问题:

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

穆铭晨
2023-03-14

我正在开发一个应用程序,它需要在Secp256R1(NIST P-256,P-256,prime256v1)公钥的帮助下验证SHA256和ECDSA签名。

公钥是由一个不同的应用程序在较早的时间点生成的,并以十六进制编码存储在我的数据库中。这里的十六进制字符串的格式等效于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);
}

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)。我可以做什么来解析这个?

共有1个答案

慕胡媚
2023-03-14

关于椭圆曲线、密钥对生成和密钥工厂的Bouncy Castle示例代码让我非常接近。

一旦我设法为Secp256R1//NIST P-256/P-256/Prime256v1曲线创建了ECDSA密钥工厂和曲线规范,我就可以使用Ecpoint.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;
}

 类似资料:
  • 问题内容: 我正在开发一个需要借助(NIST P-256,P-256,prime256v1)公钥来验证签名的应用程序。 公钥是由其他应用程序在较早的时间点生成的,并以十六进制编码存储在我的数据库中。十六进制字符串的格式等效于OpenSSL在调用以前由生成的文件时将生成的十六进制字符串。消息和签名是从其他应用程序接收的。考虑以下测试数据: 现在,这 应该 是有效的签名。 我的目标是使用Java和/或

  • 我在web上找到的示例建议使用PublicKeyFactory.createKey,我是这样做的: 不幸的是,这给了我一个异常“GetInstance中的未知对象:org.bouncycastle.asn1.derInteger\n参数名称:obj” 我猜这与密钥在字节数组中的编码方式有关。不幸的是,这不是我能控制的;但它也不是完全搞砸了,因为当我对包含密钥数据的bin文件运行时,OpenSSL命

  • 问题内容: 我正在尝试学习一些加密编码,并生成了当前保存在字节数组中的32字节私有密钥( byte [] privatekey )。我知道公钥是使用 secp256k1 命名为椭圆曲线参数和一个公式生成的,其中,其中G是椭圆曲线上的某个点(ECPoint?),但是我无法将该命名参数的规范和公式转换为的实际编码公钥。我知道自Java 7起,and包中包含一些类,以简短的代码即可完成此操作,但是我找不

  • 我从服务器获得了以下jwks 我有一个加密的令牌。我想用上面的jwk解密它。如何从上述jwk中获取公钥。我从楼梯上走下来https://auth0.com/docs/quickstart/backend/rails/01-authorization.但上述jwk中缺少x5c(证书)。 我想知道在jwk中没有x5c如何获取公钥。

  • 您可以在AWS KMS中创建非对称密钥对(加密/解密)。当前AWS CLI允许访问公钥(https://awscli.amazonaws.com/v2/documentation/api/latest/reference/kms/get-public-key.html) 我无法在Terraform的KMS资源中看到这一点。是我错过了什么还是这只是在最新版本中还没有,

  • 我已经阅读了如何在OpenSSL中从ECDSA私钥获取公钥? 并想做同样的事情,但在Java中与充气城堡。 我也见过Bouncy Castle ESCDA从私钥创建公钥,但这并没有帮助。