Code Examples – En-/Decryption with ECIES

Introduction  |  Message Digest  |  Symmetric ciphers  |  RSA  |  ECIES  |  Digital signatures (S/MIME)

Download code

En-/decryption with elliptic curve integrated encryption system (ECIES): Popular asymmetric cryptosystems like RSA are known to be very costly concerning calculation time and memory needs for larger key sizes. To solve this problem, elliptic curve cryptosystems based can be used. An elliptic curve cryptosystem is an asymmetric cryptosystem relying on the hardness of the discrete logarithm problem in elliptic curve groups. With ECIES encryption, it is possible to encrypt data with a 160-bit key as secure as with RSA using a 1024-bit key. So ECIES encryption is the better choice compared to RSA when calculation time and available memory are restricted, e.g. when using cryptosystems on smartcards.

In this example, we will use ECIES to encrypt and decrypt a file stored on the local disk. We will see that this procedure is very similar to the encryption with RSA, so some explanations will only point to the code example for RSA encryption. Reading and understanding that code snippet is recommended before trying to understand this one.

First, we do the necessary imports:

01 import java.io.FileInputStream;
02 import java.io.FileOutputStream;
03 import java.security.KeyPair;
04 import java.security.KeyPairGenerator;
05 import java.security.PrivateKey;
06 import java.security.PublicKey;
07 import java.security.SecureRandom;
08 import java.security.Security;
09
10 import javax.crypto.Cipher;
11 import javax.crypto.CipherInputStream;
12 import javax.crypto.CipherOutputStream;
13
14 import de.flexiprovider.common.ies.IESParameterSpec;
15 import de.flexiprovider.core.FlexiCoreProvider;
16 import de.flexiprovider.ec.FlexiECProvider;
17 import de.flexiprovider.ec.parameters.CurveParams;
18 import de.flexiprovider.ec.parameters.CurveRegistry.BrainpoolP160r1;
19
20 public class ExampleECIES {
21
22 public static void main(String[] args) throws Exception {
23
24 Security.addProvider(new FlexiCoreProvider());
25 Security.addProvider(new FlexiECProvider());

Please note that in line 25, we register the FlexiECProvider in additon to the FlexiCoreProvider since the algorithms needed for this code example are implemented there.

For using an elliptic curve cryptosystem, we must set the right parameters for the curve and generate valid keys for encryption (public) and decryption (private). We use the KeyPairGenerator class as explained in the RSA example:

27 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECIES", "FlexiEC");
28
29 CurveParams ecParams = new BrainpoolP160r1();
30
31 kpg.initialize(ecParams, new SecureRandom());
32 KeyPair keyPair = kpg.generateKeyPair();
33 PublicKey pubKey = keyPair.getPublic();
34 PrivateKey privKey = keyPair.getPrivate();

In line 27, we call the static getInstance(String algorithm) method of the KeyPairGenerator class with "ECIES" as paramater to obtain a key pair generator for ECIES key pairs.

In line 29, we obtain a set of EC domain parameters (curve parameters) used for the key pair generator and also for ECIES later on. The FlexiECProvider contains a a number of predefined curve parameters which are defined in the CurveRegistry class. Here, a 160-bit elliptic curve is used. For more information about EC domain parameters, please refer to the pertinent literature.

In line 31, we initialize the key pair generator with these curve parameters and a source of randomness. Then, the encryption and decryption keys are generated in lines 32–34.

Now we are ready to create a Cipher object operating with the ECIES algorithm:

38 Cipher cipher = Cipher.getInstance("ECIES", "FlexiEC");
39
40 IESParameterSpec iesParams = new IESParameterSpec("AES128-CBC",
41 "HmacSHA1", null, null);
42
43 cipher.init(Cipher.ENCRYPT_MODE, pubKey, iesParams);

As known from the RSA example, we use the static getInstance(String algorithm, String provider) method of the Cipher class in line 38 to obtain the desired instance of ECIES. In lines 40 and 41, a parameters set for ECIES is generated, using the EC domain parameters specified above. In addition, the symmetric encryption algorithm and the MAC algorithm used by ECIES are specified. The cipher is then initialized for encryption in line 43.

The following encryption process is identical to the RSA example, the only difference is that the cipher stream operates with a Cipher object initialized for the ECIES algorithm:

45 String cleartextFile = "cleartext.txt";
46 String ciphertextFile = "ciphertextECIES.txt";
47
48 byte[] block = new byte[64];
49 FileInputStream fis = new FileInputStream(cleartextFile);
50 FileOutputStream fos = new FileOutputStream(ciphertextFile);
51 CipherOutputStream cos = new CipherOutputStream(fos, cipher);
52
53 int i;
54 while ((i = fis.read(block)) != -1) {
55 cos.write(block, 0, i);
56 }
57 cos.close();

The following part shows the decryption of the encrypted cleartext above. First, the Cipher object is initialized for decryption. Then, cipher streams are used to decrypt the data again.

61 String cleartextAgainFile = "cleartextAgainECIES.txt";
62
63 cipher.init(Cipher.DECRYPT_MODE, privKey, iesParams);
64
65 fis = new FileInputStream(ciphertextFile);
66 CipherInputStream cis = new CipherInputStream(fis, cipher);
67 fos = new FileOutputStream(cleartextAgainFile);
68
69 while ((i = cis.read(block)) != -1) {
70 fos.write(block, 0, i);
71 }
72 fos.close();
73 }
74
75 }

The decrypted cleartext is now contained in the file "cleartextAgainECIES.txt".

Druckerenglisch deutsche Flagge   Impressum