Skip to main content
2 of 2
deleted 488 characters in body; edited tags; edited title
Jamal
  • 34.9k
  • 13
  • 133
  • 237

Encryption/decryption of data

I'm trying to work with some encryption/decryption of data. It was some hard work for me to get it working with some buffers and what not.

This is the code I came up with:

public static string Encrypt(string dataToEncrypt, byte[] publicKeyInfo)
{
    //// Our bytearray to hold all of our data after the encryption
    byte[] encryptedBytes = new byte[0];
    using (var rsa = new RSACryptoServiceProvider())
    {
        try
        {
            var encoder = new UTF8Encoding();

            byte[] encryptThis = encoder.GetBytes(dataToEncrypt);

            //// Importing the public key
            rsa.ImportCspBlob(publicKeyInfo);

            int blockSize = (rsa.KeySize / 8) - 32;

            //// buffer to write byte sequence of the given block_size
            byte[] buffer = new byte[blockSize];

            byte[] encryptedBuffer = new byte[blockSize];

            //// Initializing our encryptedBytes array to a suitable size, depending on the size of data to be encrypted
            encryptedBytes = new byte[encryptThis.Length + blockSize - (encryptThis.Length % blockSize) + 32];

            for (int i = 0; i < encryptThis.Length; i += blockSize)
            {
                //// If there is extra info to be parsed, but not enough to fill out a complete bytearray, fit array for last bit of data
                if (2 * i > encryptThis.Length && ((encryptThis.Length - i) % blockSize != 0))
                {
                    buffer = new byte[encryptThis.Length - i];
                    blockSize = encryptThis.Length - i;
                }

                //// If the amount of bytes we need to decrypt isn't enough to fill out a block, only decrypt part of it
                if (encryptThis.Length < blockSize)
                {
                    buffer = new byte[encryptThis.Length];
                    blockSize = encryptThis.Length;
                }

                //// encrypt the specified size of data, then add to final array.
                Buffer.BlockCopy(encryptThis, i, buffer, 0, blockSize);
                encryptedBuffer = rsa.Encrypt(buffer, false);
                encryptedBuffer.CopyTo(encryptedBytes, i);
            }
        }
        catch (CryptographicException e)
        {
            Console.Write(e);
        }
        finally
        {
            //// Clear the RSA key container, deleting generated keys.
            rsa.PersistKeyInCsp = false;
        }
    }
    //// Convert the byteArray using Base64 and returns as an encrypted string
    return Convert.ToBase64String(encryptedBytes);
}




public static string Decrypt(string dataToDecrypt, byte[] privateKeyInfo)
{
    //// The bytearray to hold all of our data after decryption
    byte[] decryptedBytes;

    //Create a new instance of RSACryptoServiceProvider.
    using (var rsa = new RSACryptoServiceProvider())
    {
        try
        {
            byte[] bytesToDecrypt = Convert.FromBase64String(dataToDecrypt);

            //// Import the private key info
            rsa.ImportCspBlob(privateKeyInfo);

            //// No need to subtract padding size when decrypting
            int blockSize = rsa.KeySize / 8;

            //// buffer to write byte sequence of the given block_size
            byte[] buffer = new byte[blockSize];

            //// buffer containing decrypted information
            byte[] decryptedBuffer = new byte[blockSize];

            //// Initializes our array to make sure it can hold at least the amount needed to decrypt.
            decryptedBytes = new byte[dataToDecrypt.Length];

            for (int i = 0; i < bytesToDecrypt.Length; i += blockSize)
            {
                if (2 * i > bytesToDecrypt.Length && ((bytesToDecrypt.Length - i) % blockSize != 0))
                {
                    buffer = new byte[bytesToDecrypt.Length - i];
                    blockSize = bytesToDecrypt.Length - i;
                }

                //// If the amount of bytes we need to decrypt isn't enough to fill out a block, only decrypt part of it
                if (bytesToDecrypt.Length < blockSize)
                {
                    buffer = new byte[bytesToDecrypt.Length];
                    blockSize = bytesToDecrypt.Length;
                }

                Buffer.BlockCopy(bytesToDecrypt, i, buffer, 0, blockSize);
                decryptedBuffer = rsa.Decrypt(buffer, false);
                decryptedBuffer.CopyTo(decryptedBytes, i);
            }
        }
        finally
        {
            //// Clear the RSA key container, deleting generated keys.
            rsa.PersistKeyInCsp = false;
        }
    }

    //// We encode each byte with UTF8 and then write to a string while trimming off the extra empty data created by the overhead.
    var encoder = new UTF8Encoding();
    return encoder.GetString(decryptedBytes).TrimEnd(new[] { '\0' });

}

I tried to see if I could split it up, but in my effort to do so, I came up with what I believed would be a more complex method (higher cyclomatic complexity). I had a lot of if statements all of the sudden, having to take care of the encryption mode but also handling the encoding from UTF8 or BASE64.