Как преобразовать шестнадцатеричный открытый ключ в структуру SubjectPublicKeyInfo ASN.1 для обмена ключами Диффи-Хеллмана? - PullRequest
1 голос
/ 05 апреля 2019

Я пытаюсь реализовать обмен ключами Диффи-Хеллмана для генерации симметричного ключа для шифрования / дешифрования с использованием пакетов криптографии 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);

Hex PublicKey - ошибка:

    String testPublicKey = "85f04dd00345642ad12b65bd1a7c38728bff0b8e281ddb6ac4f2739e82a02145daabf23d173c933913b1f844059710e9125591569de427eae1d269accbfa3305069deb7622d1da3ad9820d11bd24fdcce5381d2df99bda314394738dfcbe210eae247b1303e79297ff746cd919e189f6a5776e6ecc24c8900de0f38f159072de";
    X509EncodedKeySpec testPubKeySpec = new X509EncodedKeySpec(hexStringToByteArray(testPublicKey));
    KeyFactory keyFactory = KeyFactory.getInstance("DiffieHellman");
    PublicKey clientPubKey = keyFactory.generatePublic(testPubKeySpec);//Failing here

байт [], созданный в первом блоке кода, имеет открытый ключ в кодированном формате ASN.1, но hexStringToByteArray (testPublicKey) просто преобразует гекс в байт [].Получение ошибки ниже на отмеченной линии, из-за этого.

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 Ответ

1 голос
/ 05 апреля 2019

Если у вас уже есть параметры домена (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));
...