如何将十六进制公钥转换为ASN.1 SubjectPublicKeyInfo结构以进行Diffie-Hellman密钥交换?

时间:2019-04-05 13:49:58

标签: java public-key asn.1 diffie-hellman public-key-exchange

我正在尝试实现Diffie-Hellman密钥交换,以使用JAVA加密软件包生成用于加密/解密的对称密钥。这要求两方之间进行公共密钥交换。

客户端共享的公共密钥为1024位十六进制字符串,应使用该密钥来计算共享密钥。如何将此字符串转换为编码的密钥格式(ASN.1 SubjectPublicKeyInfo结构)以创建PublicKey对象。

考虑样本公共密钥字符串。参数 p g 被馈入 inputDHParameterSpec 对象。

示例实施: AutoGen密钥对:

    KeyPairGenerator clientKpairGen = keyPairGenerator.getInstance("DiffieHellman");
    clientKpairGen.initialize(inputDHParameterSpec);
    KeyPair clientKpair = clientKpairGen.generateKeyPair();
    byte[] clientPubKeyEnc = clientKpair.getPublic().getEncoded();

    X509EncodedKeySpec testPubKeySpec = new X509EncodedKeySpec(clientPubKeyEnc);
    KeyFactory keyFactory = KeyFactory.getInstance("DiffieHellman");
    PublicKey clientPubKey = keyFactory.generatePublic(testPubKeySpec);

十六进制公钥-失败:

    String testPublicKey = "85f04dd00345642ad12b65bd1a7c38728bff0b8e281ddb6ac4f2739e82a02145daabf23d173c933913b1f844059710e9125591569de427eae1d269accbfa3305069deb7622d1da3ad9820d11bd24fdcce5381d2df99bda314394738dfcbe210eae247b1303e79297ff746cd919e189f6a5776e6ecc24c8900de0f38f159072de";
    X509EncodedKeySpec testPubKeySpec = new X509EncodedKeySpec(hexStringToByteArray(testPublicKey));
    KeyFactory keyFactory = KeyFactory.getInstance("DiffieHellman");
    PublicKey clientPubKey = keyFactory.generatePublic(testPubKeySpec);//Failing here
在第一个代码块中创建的

byte []具有ASN.1编码格式的公共密钥,但是 hexStringToByteArray(testPublicKey)仅将十六进制转换为byte []。因此,在标记的行上出现以下错误。

Exception in thread "main" java.security.spec.InvalidKeySpecException: Inappropriate key specification
    at com.sun.crypto.provider.DHKeyFactory.engineGeneratePublic(DHKeyFactory.java:85)
    at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
    at MWK_DHGen.main(MWK_DHGen.java:87)
Caused by: java.security.InvalidKeyException: Error parsing key encoding
    at com.sun.crypto.provider.DHPublicKey.<init>(DHPublicKey.java:178)
    at com.sun.crypto.provider.DHKeyFactory.engineGeneratePublic(DHKeyFactory.java:78)
    ... 2 more

有人可以在这里帮助将十六进制转换为所需格式吗?还鼓励使用此十六进制字符串来到达密钥的不同实现。

1 个答案:

答案 0 :(得分:1)

如果您已经具有域参数(p,g)和公钥的整数值,则可以使用DHPublicKeySpec而不是X509EncodedKeySpec

String testPublicKey = "85f04dd00345642ad12b65bd1a7c38728bff0b8e281ddb6ac4f2739e82a02145daabf23d173c933913b1f844059710e9125591569de427eae1d269accbfa3305069deb7622d1da3ad9820d11bd24fdcce5381d2df99bda314394738dfcbe210eae247b1303e79297ff746cd919e189f6a5776e6ecc24c8900de0f38f159072de";
BigInteger publicKeyInteger = new BigInteger(testPublicKey, 16);
KeyFactory keyFactory = KeyFactory.getInstance("DiffieHellman");
PublicKey clientPubKey = keyFactory.generatePublic(new DHPublicKeySpec(publicKeyInteger, g, p));