Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sajidmohammed88/0ba2e0732274a25d0a04f10bf1d5abdc to your computer and use it in GitHub Desktop.
Save sajidmohammed88/0ba2e0732274a25d0a04f10bf1d5abdc to your computer and use it in GitHub Desktop.
Encryption/Decryption by BouncyCastle nuget for .NET projects.

2 Rsa Encryption/Decryption

2.1 Create C# class BlockRsaEngine

/// <summary>
/// The block rsa engine
/// </summary>
public class BlockRsaEngine
{
    /// <summary>
    /// rsa The engine.
    /// </summary>
    private readonly IAsymmetricBlockCipher _engine;

    /// <summary>
    /// The encoding.
    /// </summary>
    private readonly Encoding _encoding;

    /// <summary>
    /// Initializes a new instance of the <see cref="BlockRsaEngine"/> class.
    /// </summary>
    /// <param name="encoding">The encoding.</param>
    public BlockRsaEngine(Encoding encoding)
    {
        _engine = new RsaEngine();
        _encoding = encoding;
    }

    /// <summary>
    /// Encrypts the specified plain.
    /// </summary>
    /// <param name="textToEncrypt">The text to encrypt.</param>
    /// <param name="key">The key.</param>
    /// <returns>(Base64, hex code)Encrypted string.</returns>
    public (string, string) Encrypt(string textToEncrypt, AsymmetricKeyParameter key)
    {
        byte[] result = BouncyCastleCrypto(true, _encoding.GetBytes(textToEncrypt), key);
        return (Convert.ToBase64String(result), string.Join("", result.Select(c => ((int)c).ToString("X2"))));
    }

    /// <summary>
    /// Decrypts the specified cipher.
    /// </summary>
    /// <param name="base64ToDecrypt">The base 64 to decrypt.</param>
    /// <param name="key">The key.</param>
    /// <returns>Decrypted string.</returns>
    public string Decrypt(string base64ToDecrypt, AsymmetricKeyParameter key)
    {
        byte[] result = BouncyCastleCrypto(false, Convert.FromBase64String(base64ToDecrypt), key);

        return _encoding.GetString(result);
    }

    /// <summary>
    /// Bouncies the castle crypto.
    /// </summary>
    /// <param name="forEncrypt">if set to <c>true</c> [for encrypt].</param>
    /// <param name="input">The input.</param>
    /// <param name="key">The key.</param>
    /// <returns>Encrypted/decrypted text.</returns>
    private byte[] BouncyCastleCrypto(bool forEncrypt, byte[] input, AsymmetricKeyParameter key)
    {
        try
        {
            _engine.Init(forEncrypt, key);
            return _engine.ProcessBlock(input, 0, input.Length);
        }
        catch (CryptoException ex)
        {
            throw new CryptoException($"Exception during RSA Encryption/Decryption - error: {ex.Message}");
        }
    }

    /// <summary>
    /// Reads the public key.
    /// </summary>
    /// <param name="publicKeyFileName">The public key file name.</param>
    /// <returns>The public key.</returns>
    public AsymmetricKeyParameter ReadPublicKey(string publicKeyFileName)
    {
        using var reader = File.OpenText(publicKeyFileName);
        return (AsymmetricKeyParameter)new PemReader(reader).ReadObject();
    }

    /// <summary>
    /// Reads the private key.
    /// </summary>
    /// <param name="privateKeyFileName">Name of the private key file.</param>
    /// <returns>The private key.</returns>
    public AsymmetricKeyParameter ReadPrivateKey(string privateKeyFileName)
    {
        using var reader = File.OpenText(privateKeyFileName);
        return ((AsymmetricCipherKeyPair)new PemReader(reader).ReadObject())?.Private;
    }

    /// <summary>
    /// Generates the keys.
    /// </summary>
    /// <returns>(private key, public key)</returns>
    public (AsymmetricKeyParameter, AsymmetricKeyParameter) GenerateKeys()
    {
        //RSA key pair constructor 
        RsaKeyPairGenerator keyGenerator = new RsaKeyPairGenerator();
        // RSA key constructor parameters 
        RsaKeyGenerationParameters param = new RsaKeyGenerationParameters(
            Org.BouncyCastle.Math.BigInteger.ValueOf(3),
            new Org.BouncyCastle.Security.SecureRandom(),
            1024, //key length 
            25);

        // Initialize the key constructor with parameters 
        keyGenerator.Init(param);
        AsymmetricCipherKeyPair keyPair = keyGenerator.GenerateKeyPair();
        return (keyPair.Private, keyPair.Public);
    }

2.2 - Call Encrypt/Decrypt method, Create EncryptDecryptTextByRsa method for example :

/// <summary>
/// Encrypts the decrypt text by RSA.
/// </summary>
private static void EncryptDecryptTextByRsa()
{
    try
    {
        string plain = "mohammed sajid";
        BlockRsaEngine blockRsaEngine = new BlockRsaEngine(Encoding.UTF8);
        
        //Generate new private/public key.
        //var generatedKeys = blockRsaEngine.GenerateKeys();

        // use existing private/public key.
        AsymmetricKeyParameter publicKey = blockRsaEngine.ReadPublicKey(@"Encryption/PublicKey.txt");
        AsymmetricKeyParameter privateKey = blockRsaEngine.ReadPrivateKey(@"Encryption/PrivateKey.txt");

        Console.WriteLine("*******************************Encryption******************************");

        var encryptedPlain = blockRsaEngine.Encrypt(plain, publicKey);
        Console.WriteLine($"Encrypted text : {plain} - by publicKey is :");
        Console.WriteLine($"For Hex : {Environment.NewLine}{encryptedPlain.Item2.ToLower()}");
        Console.WriteLine($"For Base64 : {Environment.NewLine}{encryptedPlain.Item1}");

        Console.WriteLine("*******************************Decryption*******************************");

        string decryptedPlain = blockRsaEngine.Decrypt(encryptedPlain.Item1, privateKey).ToLower();
        Console.WriteLine($"Decrypted base64 : {encryptedPlain.Item1}, by privateKey is : {decryptedPlain}");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

4 - Call the method EncryptDecryptText in the Main function for Console project.

public static void Main(string[] args)
{
    EncryptDecryptTextByRsa();
}

5 - Result of the test :

*******************************Encryption******************************
Encrypted text : mohammed sajid - by publicKey is :
For Hex :
97fa768cdd80326ea9ac5ae9bedf9bf9a97480e69254ac0367f2f3e5bae7a4a8c09cad5b3912f6b5
4c3a1672b733d73bd0a34a45be68ce54e8161cf020187af259cdc8c3c6d0975c47bfcf7cdf134d29
3ca546d2342de1bd1709062e2a270f3faaa9511b47819a53e7b6873e2e8ed48192098c44ec99b2e9
c0ac5463023f3876
For Base64 :
l/p2jN2AMm6prFrpvt+b+al0gOaSVKwDZ/Lz5brnpKjAnK1bORL2tUw6FnK3M9c70KNKRb5ozlToFhzw
IBh68lnNyMPG0JdcR7/PfN8TTSk8pUbSNC3hvRcJBi4qJw8/qqlRG0eBmlPntoc+Lo7UgZIJjETsmbLp
wKxUYwI/OHY=
*******************************Decryption*******************************
Decrypted base64 : l/p2jN2AMm6prFrpvt+b+al0gOaSVKwDZ/Lz5brnpKjAnK1bORL2tUw6FnK3M
9c70KNKRb5ozlToFhzwIBh68lnNyMPG0JdcR7/PfN8TTSk8pUbSNC3hvRcJBi4qJw8/qqlRG0eBmlPnt
oc+Lo7UgZIJjETsmbLpwKxUYwI/OHY=, by privateKey is : mohammed sajid


3 EAS encryption/Decryption

3.1 Create C# class BlockCipherEngine

/// <summary>
/// The block cipher engine
/// </summary>
public class BlockCipherEngine
{
    /// <summary>
    /// The encoding.
    /// </summary>
    private readonly Encoding _encoding;

    /// <summary>
    /// The block cipher.
    /// </summary>
    private readonly IBlockCipher _blockCipher;

    /// <summary>
    /// The buffered block cipher
    /// </summary>
    private PaddedBufferedBlockCipher _bufferedBlockCipher;

    public BlockCipherEngine(IBlockCipher blockCipher, Encoding encoding)
    {
        _blockCipher = blockCipher;
        _encoding = encoding;
    }

    /// <summary>
    /// Encrypts the specified plain.
    /// </summary>
    /// <param name="textToEncrypt">The text to encrypt.</param>
    /// <param name="key">The key.</param>
    /// <returns>Encrypted string.</returns>
    public string Encrypt(string textToEncrypt, string key)
    {
        byte[] result = BouncyCastleCrypto(true, _encoding.GetBytes(textToEncrypt), key);
        return Convert.ToBase64String(result);
    }

    /// <summary>
    /// Decrypts the specified cipher.
    /// </summary>
    /// <param name="textToDecrypt">The text to decrypt.</param>
    /// <param name="key">The key.</param>
    /// <returns>Decrypted string.</returns>
    public string Decrypt(string textToDecrypt, string key)
    {
        byte[] result = BouncyCastleCrypto(false, Convert.FromBase64String(textToDecrypt), key);
        return _encoding.GetString(result);
    }

    /// <summary>
    /// Bouncies the castle crypto.
    /// </summary>
    /// <param name="forEncrypt">if set to <c>true</c> [for encrypt].</param>
    /// <param name="input">The input.</param>
    /// <param name="key">The key.</param>
    /// <returns>Byte.</returns>
    /// <exception cref="CryptoException"></exception>
    private byte[] BouncyCastleCrypto(bool forEncrypt, byte[] input, string key)
    {
        try
        {
            _bufferedBlockCipher = new PaddedBufferedBlockCipher(_blockCipher, new Pkcs7Padding());

            _bufferedBlockCipher.Init(forEncrypt, new KeyParameter(_encoding.GetBytes(key)));

            return _bufferedBlockCipher.DoFinal(input);
        }
        catch (CryptoException ex)
        {
            throw new CryptoException($"Exception during Encryption/Decryption - error: {ex.Message}");
        }
    }
}

3.2 - Call Encrypt/Decrypt method, Create EncryptDecryptText method for example :

private static void EncryptDecryptText()
{
    try
    {
        string keyAlias = "03072_903-072_90";
        string textToEncrypt = "mohammed sajid";

        BlockCipherEngine blockCipherEngine = new BlockCipherEngine(new AesEngine(), Encoding.ASCII);

        string encryptedPlain = blockCipherEngine.Encrypt(textToEncrypt, keyAlias);
        Console.WriteLine($"Encrypted text : {textToEncrypt}, by key : {keyAlias} is : {encryptedPlain}");

        string decryptedPlain = blockCipherEngine.Decrypt(encryptedPlain, keyAlias);
        Console.WriteLine($"Decrypted : {encryptedPlain}, by key : {keyAlias} is : {decryptedPlain}");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

3.3 - Call the method EncryptDecryptText in the Main function for Console project.

public static void Main(string[] args)
{
    EncryptDecryptText();
}

3.4 - Result of the test :

Encrypted text : mohammed sajid, by key : 03072_903-072_90 is : dAQtG62sHI30dUwHM
DcIcA==
Decrypted : dAQtG62sHI30dUwHMDcIcA==, by key : 03072_903-072_90 is : mohammed saj
id
@sajidmohammed88
Copy link
Author

sajidmohammed88 commented Feb 11, 2021

The Key length should be 128/192/256 bits, or 16/24/32 characters for EAS engine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment