2015-06-19 160 views
1

我需要使用ECDSA算法对消息进行签名并发送给接收方。然后,接收方应验证发件人的签名。将字节数组转换为publickey ECDSA

所以,对于这一点,接收器由波纹管命令转换java.security.PublicKey到字节数组之后,但在字节数组格式发送者的公钥:

byte[] byteArrayPublicKey = publickey.getEncoded(); 

在ECDSA算法(公共密钥将其转换为之前的格式字节数组)是如下:

公钥:

X: 8a83c389e7bb817c17bf2db4ed71055f18342b630221b2a3a1ca752502dc2e21 

Y: 3eaf48c9ab1700fe0966a0cde196b85af66bb8f0bacef711c9dca2368f9d8470 

但是,问题是该字节数组转换为可用的格式到v通过接收器验证java.security.PublicKey的签名。

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

+0

如果你的'PublicKey.getEncoded()'的结果是**不**只是公共点X和Y;它还包含一个包含参数的AlgId。 Java调用“X509”编码,你可以直接将它提供给'KeyFactory.getInstance(“EC”)。generatePublic()'。如果你实际上只有单独的点坐标**和曲线**,请参阅http://stackoverflow.com/questions/22646792/how-does-one-convert-a-public-ec-code-point-and-curve -name-into-a-publickey和http://stackoverflow.com/questions/30445997/loading-raw-64-byte-long-ecdsa-public-key-in-java。 –

回答

2

但问题是将此字节数组转换为可用格式来验证接收方是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符号/验证的完整运行代码。你可以看看更好的理解。

+0

Rakeb无效,非常感谢您的有用和伟大的答案。只是应该补充另一件事,我在另一个问题在这里解释它: http://stackoverflow.com/questions/30956867/signature-verification-is-always-false-java?noredirect=1#comment49946507_30956867 这件事是尊重ASN.1进行签名和验证。 – sas

+0

如果这是您正在寻找的答案,然后尝试接受它。 TY。 –

+0

我试着为它投票接受这个答案,但实际上,这至少需要15个声望。我的声誉是7.我尽可能的尽快做到这一点,我可以投票。 – sas