Insou
Insou

Reputation: 1383

Java/Android - ECDH Encryption - Create ECPublicKey from String

I have a little problem with the ECDH (Elliptic-curve Diffie-Hellman) encryption. I use the BouncyCastle library.

Here is my function to generate keys :

public static KeyPair generateECKeys() {
    try {
        ECNamedCurveParameterSpec parameterSpec = ECNamedCurveTable.getParameterSpec("brainpoolp256r1");
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDH", "BC");

        keyPairGenerator.initialize(parameterSpec);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        return keyPair;
    } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException | NoSuchProviderException e) {
        Log.d("Error - ",e.getMessage());
        e.printStackTrace();
        return null;
    }
}

I encode my public key in base64 with :

String keyPairA_public_base64 = Base64.getEncoder().encodeToString(keyPairA.getPublic().getEncoded());

Here is an example of the key received :

keyPairA_public_base64 = "MFowFAYHKoZIzj0CAQYJKyQDAwIIAQEHA0IABGuSxmgwVGLHwcVhSf7C4/BfxfL4pGixHht8rWjPMBMTH5Vav1RQnf/Ucv9rLpD3M6ad8hHotwP5IpFsQT3hRkg="

Now, I need to generate an ECPublicKey object with the public key (String).

ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("brainpoolp256r1");
KeyFactory kf = KeyFactory.getInstance("ECDH", new BouncyCastleProvider());
ECNamedCurveSpec params = new ECNamedCurveSpec("brainpoolp256r1", spec.getCurve(), spec.getG(), spec.getN());
ECPoint point =  ECPointUtil.decodePoint(params.getCurve(), keyPairA.getPublic().getEncoded()); // Error here : Invalid point encoding 0x30
ECPublicKeySpec pubKeySpec = new java.security.spec.ECPublicKeySpec(point, params);
ECPublicKey pk = (ECPublicKey) kf.generatePublic(pubKeySpec);

But, I have an error : Invalid point encoding 0x30 when I use ECPointUtil.decodePoint()

I don't understand how I can solve this error and if I use the right way to create an ECPublicKey object from a string.

Can you help me please ? :)

Upvotes: 3

Views: 1442

Answers (1)

Topaco
Topaco

Reputation: 49400

ECPointUtil.decodePoint() expects a raw public key. keyPairA_public_base64 on the other hand is a Base64 encoded public key in X.509/SPKI format (i.e. not a raw public key) and can be imported as follows:

import java.security.spec.X509EncodedKeySpec;
import java.security.interfaces.ECPublicKey;
import java.security.KeyFactory;
...
X509EncodedKeySpec x509EncodedKeySpecA = new X509EncodedKeySpec(Base64.getDecoder().decode(keyPairA_public_base64));
KeyFactory keyFactoryA = KeyFactory.getInstance("ECDH");
ECPublicKey publicKeyA = (ECPublicKey)keyFactoryA.generatePublic(x509EncodedKeySpecA);

Upvotes: 2

Related Questions