3

我需要使用 ECDSA 算法对消息进行签名并在 java 中发送给接收者。然后,接收方应验证发送方的签名。

因此,为此,接收方拥有发送方的公钥,但在java.security.PublicKey通过以下命令转换为字节数组后采用字节数组格式:

byte[] byteArrayPublicKey = publickey.getEncoded();

ECDSA算法中公钥的格式(转换为字节数组前)如下:

公钥:

X: 8a83c389e7bb817c17bf2db4ed71055f18342b630221b2a3a1ca752502dc2e21

Y: 3eaf48c9ab1700fe0966a0cde196b85af66bb8f0bacef711c9dca2368f9d8470

但是,问题是将此字节数组转换为可用格式以验证java.security.PublicKey接收者的签名。

一般来说,是否有任何解决方案来验证签名而不将其转换为字节数组?换句话说,问题是通过发送者的公钥,使用任何方法来验证签名。

4

1 回答 1

3

但是,问题是将此字节数组转换为可用格式,以验证接收者的签名是 java.security.PublicKey。

您可以这样解决问题:

public static ECPublicKey genEcPubKey() throws Exception {
    KeyFactory factory = KeyFactory.getInstance("ECDSA", "BC");
    java.security.PublicKey ecPublicKey = (ECPublicKey) factory
            .generatePublic(new X509EncodedKeySpec(Helper
                    .toByte(ecRemotePubKey))); // Helper.toByte(ecRemotePubKey)) is java.security.PublicKey#getEncoded()
    return (ECPublicKey) ecPublicKey;
}

请注意,您需要BouncyCastle提供程序来执行此操作。

但问题仍然存在,您如何生成私钥?

public KeyPair ecKeyPairGenerator(String curveName) throws Exception {
    KeyPair keyPair;
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
            "ECDSA", "BC");
    ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec(
            curveName);
    keyPairGenerator.initialize(ecGenParameterSpec, new SecureRandom());
    keyPair = keyPairGenerator.generateKeyPair();
    java.security.PublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();
    System.out.println("JAVA EC PublicKey: "
            + Helper.toHex(ecPublicKey.getEncoded()));

    // write private key into a file. Just for testing purpose
    FileOutputStream fileOutputStream = new FileOutputStream(
            "ECPrivateKey.key");
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(
            fileOutputStream);
    objectOutputStream.writeObject(keyPair.getPrivate());
    objectOutputStream.close();
    return keyPair;
}

我在github中有 EC 签名/验证的完整运行代码。你可以看看更好的理解。

于 2015-06-19T21:04:59.240 回答