1

I try to encrypt/decrypt messages using a EC key. I created the key ussing openssl:

openssl ecparam -name prime256v1 -genkey -noout -out secp256r1-key.pem
openssl ec -in secp256r1-key.pem -pubout -out secp256r1-pub.pem
openssl req -new -key secp256r1-key.pem -x509 -nodes -days 99999 -out secp256r1-cert.pem

Created a java spring boot app using bouncy castle library for encryption:

   public String encrypt_1(final String msg, PublicKey publicKey) throws Exception {

        final IESCipher c1 = new org.bouncycastle.jcajce.provider.asymmetric.ec.IESCipher.ECIES();

        final Cipher cipher;
        cipher = Cipher.getInstance("ECIES");

        final byte[] msgBytes = msg.getBytes("UTF-8");

        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        final byte[] encryptedBytes = cipher.doFinal(msgBytes);

        return Base64.getEncoder().encodeToString(encryptedBytes);

    }

    public String decrypt_1(final String msgEncrypted, PrivateKey privateKey) throws Exception {
        final Cipher cipher = Cipher.getInstance("ECIES");

        final byte[] msgBytes = Base64.getDecoder().decode(msgEncrypted);

        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        final byte[] decryptedJwtBytes = cipher.doFinal(msgBytes);

        return new String(decryptedJwtBytes, StandardCharsets.US_ASCII);
    }

This works as I have output. However when I see other people implementing ECIES in java they use IESParameterSpec and IEKeySpec with as input both public and private key of both own and foreign key (as it is asymetric). An example can be found here: https://gist.github.com/amrishodiq/9821413 or on stackOverflow: ECC algorithm key mismatch

They do something like:

...
        IESParameterSpec param = new IESParameterSpec(d, e, 256);

        // decrypt the text using the private key
        bcipher.init(Cipher.DECRYPT_MODE, new IEKeySpec(tpPrivateKey, ownPublicKey), param);
        final byte[] decryptedBytes = bcipher.doFinal(cipherTextBytes);

...

I can't get that code to work, but I want to know if this is more secure and why both keys are used at the same time during encryption/decryption.

Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
BarbetNL
  • 408
  • 2
  • 16

1 Answers1

1

You're missing some fundamental understanding here.

You cannot encrypt per se with elliptic curves (ElGamal with an elliptic curve group is an exception, but not used in practice).

"Encryption" in the context of elliptic curves is really the following process:

  • Knowing that an EC private key is a large number, and an EC public key is a (x,y) point on the curve's Cartesian plane.
  • Generating a shared symmetric key via elliptic curve Diffie Hellman.
  • This ECDH process requires input from two parties, where each party effectively calculates their private key * public point A * public point B.
  • This calculation will yield another shared secret point on the curve, next the x co-ordinate component of this new point is used and passed through a hashing function to generate uniform key material.
  • Finally, you use this key with a strong symmetric cipher, preferably something like ChaCha20-Poly1305.

In summary, with EC crypto, first we do a little dance to agree a key, then we can use any symmetric cipher we like.

It's that simple, don't get mired in unnecessary detail. Also move to a different library like libsodium if possible, BC is noisy.

Finally,

        byte[]  d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
        byte[]  e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
        IESParameterSpec param = new IESParameterSpec(d, e, 256);

The above "derivation and encoding vectors" are worthless.

Woodstock
  • 22,184
  • 15
  • 80
  • 118
  • Thanks for the comprehensive answer. I was able to read a bit more into this and indeed came to the conclusion there has to be calculated some sort of private key from both keys, that will eventually encrypt/decrypt the message. I'm still not sure how to do this with BC. I've never heard of lobsodium, I'll look into it. ---- One question: do you know where I can find what symmetric ciphers I can use with the keys I have? And do you have an example implementation in java. The reason I ask is I see a lot of implementation of which I doubt it's security. – BarbetNL Jun 28 '22 at 11:23
  • @BarbetNL sorry for the delay... when you derive keys with most modern elliptic curves you'll get a 256-bit symmetric key. So you can use any algo that works with that, really you should chose either AES in GCM mode, Salsa20 or ChaCha20, the latter two with Poly1305. – Woodstock Jul 01 '22 at 07:57
  • Thanks @Woodstock . I have finished the application and have learned much more about elliptic curves now. I chose to use AES-GCM with the symmetric key. – BarbetNL Jul 14 '22 at 09:50