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.