There is Alice and Bob. I want to realize the following process:
- Alice encrypts a text with AES and generates a secret key
- Alice encrypts this secret key with Bobs public key using Elliptic Curves with El Gamal
- Alice sends the encrypted text & encrypted secret key to Bob
- Bob decrypts the secret key with his private key
- Bob decrypts the text with the decrypted secret key
- Done
I am using the class ECElGamalEncryptor from bouncycastle. My problem is, that as far as I understand, this class encrypts a point on an Elliptic Curve using a public key but my AES secret key is not a ECPoint but a Hexadecimal.
Lets pretend I have this 128-Bit Secret Key for the AES encryption:
6D5A7134743777397A24432646294A40
And this is what I have so far:
import java.math.BigInteger;
import java.security.SecureRandom;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.asn1.sec.SECNamedCurves;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.ec.ECElGamalDecryptor;
import org.bouncycastle.crypto.ec.ECElGamalEncryptor;
import org.bouncycastle.crypto.ec.ECPair;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.math.ec.ECPoint;
class TestClass {
public static void main(String[] argv) {
// Get domain parameters for example curve secp256r1
X9ECParameters ecp = SECNamedCurves.getByName("secp256r1");
ECDomainParameters domainParams = new ECDomainParameters(ecp.getCurve(),
ecp.getG(), ecp.getN(), ecp.getH(),
ecp.getSeed());
// Generate a private key and a public key
AsymmetricCipherKeyPair keyPair;
ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters(domainParams, new SecureRandom());
ECKeyPairGenerator generator = new ECKeyPairGenerator();
generator.init(keyGenParams);
keyPair = generator.generateKeyPair();
ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters) keyPair.getPrivate();
ECPublicKeyParameters publicKey = (ECPublicKeyParameters) keyPair.getPublic();
byte[] privateKeyBytes = privateKey.getD().toByteArray();
// Get ECPoint Q from privateKey
ECPoint Q = domainParams.getG().multiply(new BigInteger(privateKeyBytes));
//Initialize ECElGamalEncryptor
ECElGamalEncryptor elgamalEn = new ECElGamalEncryptor();
elgamalEn.init(publicKey);
ECPair encrypted = elgamalEn.encrypt(Q);
//Encryption
ECElGamalDecryptor elgamalDe = new ECElGamalDecryptor();
elgamalDe.init(privateKey);
ECPoint original = elgamalDe.decrypt(encrypted);
}
}
So I am able to initialize the ECElGamalEncryptor and to encrypt ECPoint Q with the public Key. But actually, I want to encrypt the AES Secret key and I have no idea what I have to do now.
Let me try rephrasing a part of your question to make it much more clear along with some symbols necessary. The way you worded your scheme is slightly tedious to understand. However, as @JamesKPolk and @MaartenBodewes pointed out what you'd need for Elliptic Curve cryptography which supports encryption is an IES scheme called ECIES which can be obtained as a combination of the ECDH and a Symmetric encryption scheme like AES for example. So let's revisit the scheme you've been trying to implement with Alice and Bob.
Bootstrap
SecretKeyand anIV. In this example we'll useAES256Scheme Desired
mwith AES to generate encrypted message em.SecretKeyused for encryption and anIVvector. In the code example that'll follow we'll call this tuple as anAESPair.SecretKey (SK) || IVmessage with Bobs public key using ECIES to obtain esk||iv.SharedSecretusing Alice's Private Key and Bob's Public Key. Let's call this SSK1SharedSecetusing Bob's Private Key and Alice's Public Key. Let's call this SSK2Code
Helper Functions
ECC.java
AES256.java
AESPair.java which is the corresponding helper for AES.
Now that we have the pieces we need, let's put together the scheme desired as a test.
Here's a run from the test:
Explanation of the test case code
Alice"plain text from alice to bob"is encrypted by Alice using the key generated in step 1.key || IVof Alice's key. This is the message that should be encrypted and sent to Bob via ECIES.ECC.generateKeyPair()method.Shared Secretwhich is a symmetricSecretKeybyte[]which is converted to anAESPairobject creating theSecretKeyandIVnecessary."plain text from alice to bob"Hope this helps. Do let me know if you wanted some clarifications.