4

ECDH secp384r1 公開/秘密鍵ペアの生成に Android で SpongyCastle を使用しようとしています。私が直面している問題は、生成しているキーが大きすぎることです。

公開鍵は 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 に頼っています。

主な問題は、これは既に CryptoPP 実装を使用している iOS アプリで動作する必要があることです。そのため、可能であれば、そのバージョンでこのラインナップを作成する方法を理解する必要があります。

基本的に、次の C++ cryptopp 実装と一致する Java SpongyCastle 実装が必要です。

   // 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;

最初のステップは、SpongyCastle 実装から 49 バイトと 48 バイトの圧縮キーを抽出する方法を理解する必要があることです。

その後、これらのキーを使用して共有シークレットを抽出することが優先されます。私は全体的な暗号化とこれらのライブラリの使用にかなり慣れていないため、ここでの助けをいただければ幸いです。

4

1 に答える 1

2

答えを導き出すことができました。次のコードは、探しているサイズのキーを提供します。

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();

朗報ですが、cryptop C++ 実装とも互換性があるようです。

于 2016-03-01T18:56:23.133 に答える