Неверный размер ключа Android SpongyCastle ECDH secp384r1

Я пытаюсь использовать SpongyCastle на Android для создания пары открытого / закрытого ключа ECDH secp384r1. Проблема, с которой я сталкиваюсь, заключается в том, что генерируемые мной ключи слишком велики.

Открытый ключ составляет 120 байтов, а закрытый ключ - 194 байта. Очевидно, здесь происходит какое-то кодирование. Мне не нужна вся эта дополнительная информация, я ищу сжатые открытые / закрытые ключи на 49 и 48 байтов.

Вот как я генерирую свои ключи:

ECGenParameterSpec ecParamSpec = new ECGenParameterSpec("secp384r1");
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDH", "SC");
kpg.initialize(ecParamSpec);

KeyPair kpA = kpg.generateKeyPair();

byte[] publicKeyBytes = kpA.getPublic().getEncoded();
byte[] privateKeyBytes = kpA.getPrivate().getEncoded();

Я иду по этому пути, потому что ранее я использовал CryptoPP и NDK для генерации пар ключей и извлечения общего секрета, который вы можете увидеть в примере здесь.

Однако я столкнулся с проблемой заставить CryptoPP работать на Android Marshmallow, поэтому теперь я прибегаю к SpongyCastle.

Основная проблема заключается в том, что это должно работать с приложением iOS, которое уже использует реализацию CryptoPP, поэтому мне нужно выяснить, как сделать эту линию с этой версией, если это вообще возможно.

В основном мне нужна реализация Java SpongyCastle, которая соответствует следующей реализации C ++ cryptopp:

   // Generate a public private key pair using ECDH (Elliptic Curve Diffie Hellman)
   OID CURVE = secp384r1(); // the key is 384 bits (48 bytes) long
   AutoSeededRandomPool rng;

   // Because we are using point compression
   // Private Key 48 bytes
   // Public Key 49 bytes
   // If compression was not used the public key would be 65 bytes long
   ECDH < ECP >::Domain dhA( CURVE );
   dhA.AccessGroupParameters().SetPointCompression(true);

   SecByteBlock privA(dhA.PrivateKeyLength()), pubA(dhA.PublicKeyLength());
   dhA.GenerateKeyPair(rng, privA, pubA);

   jobject publicKeyByteBuffer = (*env).NewDirectByteBuffer(pubA.BytePtr(), pubA.SizeInBytes());
   jobject privateKeyByteBuffer = (*env).NewDirectByteBuffer(privA.BytePtr(), privA.SizeInBytes());

   // Return the ECDH Key Pair back as a Java ECDHKeyPair object
   jclass keyPairClass = (*env).FindClass("com/tcolligan/ecdhtest/ECDHKeyPair");
   jmethodID midConstructor = (*env).GetMethodID(keyPairClass, "<init>", "(Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)V");
   jobject keyPairObject = (*env).NewObject(keyPairClass, midConstructor, publicKeyByteBuffer, privateKeyByteBuffer);

   return keyPairObject;

Первый шаг - мне нужно выяснить, как извлечь 49- и 48-байтовые сжатые ключи из реализации SpongyCastle.

После этого извлечение общего секрета с использованием этих ключей будет приоритетом. Я новичок в шифровании в целом и использую эти библиотеки, поэтому любая помощь здесь будет принята с благодарностью.


person T. Colligan    schedule 01.03.2016    source источник


Ответы (1)


Я смог найти ответ. Следующий код даст мне ключи с размерами, которые я ищу.

ECGenParameterSpec ecParamSpec = new ECGenParameterSpec("secp384r1");
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDH", "SC");
kpg.initialize(ecParamSpec);

KeyPair kpA = kpg.generateKeyPair();

BCECPublicKey publicKey = (BCECPublicKey)kpA.getPublic();
BCECPrivateKey privateKey = (BCECPrivateKey)kpA.getPrivate();

byte[] publicKeyBytes = publicKey.getQ().getEncoded(true);
byte[] privateKeyBytes = privateKey.getD().toByteArray();

Хорошая новость в том, что он, похоже, совместим с реализацией C ++ Cryptopp.

person T. Colligan    schedule 01.03.2016
comment
Использование privateKey.getD().toByteArray() может привести к непоследовательной длине результата, что может быть проблемой, если вам нужен фиксированный 48-байтовый закрытый ключ (не уверен, что это так). Вместо этого предпочитайте BigIntegers.asUnsignedByteArray(48, privateKey.getD()). - person Peter Dettman; 03.03.2016
comment
О, интересно, я понимаю, о чем вы. Я не думаю, что это будет проблемой для моей реализации, но я дважды проверю. Спасибо за внимание! - person T. Colligan; 03.03.2016
comment
пытаюсь реализовать этот ответ, но kpg.initialize (ecParamSpec); дает мне красный волнистый - person Frank Odoom; 06.08.2017