peter bence
peter bence

Reputation: 822

BouncyCastle C#: How to Implement EllipticCurve Encryption/Decryption

BouncyCastle includes many symmetric encryption engines, as well as RSA and ElGamal encryption engines (asymmetric engines). It also has a lot of online resources about how to use these engines to perform encryption/decryption processes. However, a bouncy castle provides no Elliptic Curve engine (check github/bc). After reviewing the code, all asymmetric engines implement the AsymmetricBlockCipher interface and none of them is an EC engine.

This is somehow confusing since BouncyCastle provides the ability to generate EC key pairs with different key strength based on predefined and well-known curves, like the example below:

public static AsymmetricCipherKeyPair GenerateKeys(int keySize)
{
    DerObjectIdentifier oid;
    switch (keySize)
    {
        case 192:
            oid = X9ObjectIdentifiers.Prime192v1;
            break;
        case 224:
            oid = SecObjectIdentifiers.SecP224r1;
            break;
        case 128:
            oid = SecObjectIdentifiers.SecP128r1;
            break;
        case 239:
            oid = X9ObjectIdentifiers.Prime239v1;
            break;
        case 256:
            oid = X9ObjectIdentifiers.Prime256v1;
            break;
        case 384:
            oid = SecObjectIdentifiers.SecP384r1;
            break;
        case 521:
            oid = SecObjectIdentifiers.SecP521r1;
            break;
        default:
            throw new InvalidParameterException("unknown key size.");
    }

    ECKeyPairGenerator gen = new ECKeyPairGenerator();
    SecureRandom secureRandom = new SecureRandom();
    X9ECParameters ecps = CustomNamedCurves.GetByOid(oid);
    ECDomainParameters ecDomainParameters = new ECDomainParameters(ecps.Curve, ecps.G, ecps.N, ecps.H, ecps.GetSeed());
    ECKeyGenerationParameters ecKeyGenerationParameters = new ECKeyGenerationParameters(ecDomainParameters, secureRandom);
    gen.Init(ecKeyGenerationParameters);
    return gen.GenerateKeyPair();
}

There are some engines, like IESEngine, that provides a public/private EC agreement on top of the encryption/decryption process (e.g. ECDHBasicAgreement), however, it doesn't use the public/private keys directly, instead, it calculates a new symmetric key from both keys that are then used to encrypt the plaintext message using a predefined symmetric cipher.

My question:

  1. Is BC really not providing an easy to use EC Engine like ElGamalEngine and RSAEngine?
  2. If yes, how to implement a safe EC encryption/decryption process using directly the ECKeyParameters generated using the above function (if possible)?

Thanks in advance.

Upvotes: 5

Views: 2767

Answers (2)

peter bence
peter bence

Reputation: 822

After some research, I found that BouncyCastle has its own SM2Engine that implements the SM2 Digital Signature Algorithm and uses the ECKeyParameters (Elliptic curve key parameters) to provide encryption/decryption abilities.

Edit: please note that SM2 is not yet verified to be totally secure, where there has been relatively little analysis of the SM2 signature scheme that I can find in the anglophone cryptography literature beyond some side channel attacks. So use it upon your own responsibility.

        SM2Engine sm2Engine  = new SM2Engine();
        sm2Engine.init(true, new ParametersWithRandom((ECKeyParameters) publicKey, new SecureRandom()));
        byte[] enc1 = sm2Engine.processBlock(plainText, 0, plainText.length);
        System.out.println("Cipher Text (SM2Engine): " + Hex.toHexString(enc1));
        
        sm2Engine  = new SM2Engine();
        sm2Engine.init(false, (ECKeyParameters) privateKey);
        byte[] dec1 = sm2Engine.processBlock(enc1, 0, enc1.length);
        System.out.println("Plain Text (SM2Engine): " + Hex.toHexString(dec1));

Upvotes: 3

Maarten Bodewes
Maarten Bodewes

Reputation: 94058

Is BC really not providing an easy to use EC Engine like ElGamalEngine and RSAEngine?

Correct, because there aren't any. In principle you could use ElGamal encryption with ECC, but that has such serious input limitations (requiring a point rather than normal plaintext) that it is hardly useful to do so. Furthermore, using it directly will lead to an insecure scheme. That's not specific to Bouncy Castle, by the way.

If yes, how to implement a safe EC encryption/decryption process using directly the ECKeyParameters generated using the above function (if possible)?

Unless you are a cryptographer / mathematician, you don't. You use ECIES.

Upvotes: 2

Related Questions