We need to perform encryption/decryption of some string message in java using EC key pair. key pair has been generated using secp256r1 Elliptical Curve. We just want to use java core utilities.
Encrypting code - in java server side Decryption code - it suppose to be at android and ios Key - Asymmetric EC key pair, public key readily available at java encryption side and private key readily available at android/ios decryption side. We need not to worry about key distribution, mechanism already there.
Due to encryption and decryption code present at cross platform, we want to avoid any third party library as it might not available across all three platforms - java, android, ios
ECIES, kind of encryption will work for us but how to do it in plain java utilities or with some library whihc is available across all three platforms - java, android, ios
My Sample Code(java encryption and decryption) -
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.spec.ECGenParameterSpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.bouncycastle.util.encoders.Hex;
public class Main {
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
keyGen.initialize(new ECGenParameterSpec("secp256r1"), new SecureRandom());
KeyPair ecKeyPair = keyGen.generateKeyPair();
Cipher iesCipher = Cipher.getInstance("AES/CBC/NoPadding");
Cipher iesDecipher = Cipher.getInstance("AES/CBC/NoPadding");
iesCipher.init(Cipher.ENCRYPT_MODE, ecKeyPair.getPublic());
String message = "Hello World";
byte[] ciphertext = iesCipher.doFinal(message.getBytes());
System.out.println(Hex.toHexString(ciphertext));
iesDecipher.init(Cipher.DECRYPT_MODE, ecKeyPair.getPrivate(), iesCipher.getParameters());
byte[] plaintext = iesDecipher.doFinal(ciphertext);
System.out.println(new String(plaintext));
}
public void testEncryptDecrypt() throws Exception {}
}
but above code throwing me error -
Exception in thread "main" java.security.InvalidKeyException: No installed provider supports this key: sun.security.ec.ECPublicKeyImpl
at line - iesCipher.init(Cipher.ENCRYPT_MODE, ecKeyPair.getPublic());
Please suggest what i am missing here.
You can't just use an EC key for AES.
One way to encrypt in the EC context is ECIES, a hybrid encryption scheme, which essentially uses ECDH to agree on a symmetric key that is used to symmetrically encrypt/decrypt the data. As far as I know ECIES is not possible in Java with built-in functionalities alone, i.e. you need a third party library like BouncyCastle.
Unlike ECIES, ECDH can be implemented with Java onboard means. This allows the agreement on a symmetric key, as in ECIES, which is then used to perform symmetric encryption/decryption. Since you don't want to use a third-party library, this would be a possible way:
with
Please note that this implementation does not yet include the authentication of the ciphertext (as e.g. ECIES does). This can be implemented with a MAC, alternatively a mode like GCM can be used which performs authentication implicitly.