Android SpongyCastle ECDH secp384r1 密钥大小不正确

Android SpongyCastle ECDH secp384r1 Key Size Incorrect

我正在尝试在 Android 上使用 SpongyCastle 来生成 ECDH secp384r1 Public/Private 密钥对。我 运行 遇到的问题是,我生成的密钥太大了。

public密钥为120字节,私钥为194字节。显然这里正在进行某种编码。我不想要所有这些额外的信息,我正在寻找 49 字节和 48 字节压缩的 public/private 键。

以下是我生成密钥的方式:

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 生成密钥对并提取共享密钥,您可以看到 here.

的示例

但是我 运行 想要 issue 让 CryptoPP 在 Android Marshmallow 上工作,所以现在我求助于 SpongyCastle。

主要问题是,这需要与已经在使用 CryptoPP 实现的 iOS 应用程序一起使用,所以我需要弄清楚如何使它与那个版本保持一致,如果是的话可能。

基本上我需要一个 Java 与以下 C++ cryptopp 实现一致的 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 字节的压缩密钥。

之后使用这些密钥提取共享机密将是优先事项。我对整体加密和使用这些库还很陌生,所以在这里提供任何帮助将不胜感激。

我找到了答案。以下代码将为我提供所需尺寸的钥匙。

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

好消息是,它似乎也与 cryptopp C++ 实现兼容。