如何将十六进制 public 密钥转换为 ASN.1 SubjectPublicKeyInfo 结构以进行 Diffie-Hellman 密钥交换?
How to convert hex public key to ASN.1 SubjectPublicKeyInfo structure for Diffie-Hellman key exchange?
我正在尝试实施 Diffie-Hellman 密钥交换以使用 JAVA 加密包为 encryption/decryption 生成对称密钥。这需要双方进行 public 密钥交换。
客户端共享的public密钥为1024位十六进制字符串,应该用于计算共享密钥。如何将此字符串转换为编码密钥格式(ASN.1 SubjectPublicKeyInfo 结构)以创建 PublicKey 对象。
考虑示例 public 密钥字符串。参数 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 编码格式的 public 密钥,但 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
有人可以帮助解决如何将此十六进制转换为所需格式的问题吗?还鼓励使用此十六进制字符串获得密钥的不同实现。
如果您已经有了域参数 (p, g) 和 public 键的整数值,那么 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));
我正在尝试实施 Diffie-Hellman 密钥交换以使用 JAVA 加密包为 encryption/decryption 生成对称密钥。这需要双方进行 public 密钥交换。
客户端共享的public密钥为1024位十六进制字符串,应该用于计算共享密钥。如何将此字符串转换为编码密钥格式(ASN.1 SubjectPublicKeyInfo 结构)以创建 PublicKey 对象。
考虑示例 public 密钥字符串。参数 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 编码格式的 public 密钥,但 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
有人可以帮助解决如何将此十六进制转换为所需格式的问题吗?还鼓励使用此十六进制字符串获得密钥的不同实现。
如果您已经有了域参数 (p, g) 和 public 键的整数值,那么 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));