0

I have below code written in .net framework to decrypt encrypted text and it is working fine.

private static string MD5(string testString)
{
    byte[] asciiBytes = ASCIIEncoding.ASCII.GetBytes(testString);
    byte[] hashedBytes = MD5CryptoServiceProvider.Create().ComputeHash(asciiBytes);
    string hashedString = BitConverter.ToString(hashedBytes).Replace("-", "").ToLower();
    return hashedString;
}

public static string DecryptString(string cypherText, string encryptionKey)
{
    byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
    byte[] key = ASCIIEncoding.ASCII.GetBytes(MD5(encryptionKey));

    if (key == null || key.Length <= 0)
        throw new ArgumentNullException("key");

    string plaintext;
    using (var rijAlg = new RijndaelManaged())
    {
        rijAlg.BlockSize = 256;
        rijAlg.Key = key;
        rijAlg.Mode = CipherMode.CBC;
        rijAlg.Padding = PaddingMode.Zeros;
        rijAlg.IV = ASCIIEncoding.ASCII.GetBytes(MD5(MD5(_encryptionKey)));

        ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
        using (var msDecrypt = new MemoryStream(cipherTextBytes))
        using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
        using (var srDecrypt = new StreamReader(csDecrypt))
            plaintext = srDecrypt.ReadToEnd();
    }
    return plaintext;
}

Above code never worked and was returning some junk characters when the code was migrated to .net 5. With some research and help from fellow community member I got the below updated code that works.

public static string DecryptUsingBouncyCastle(string cypherText, string keyString)
        {
            byte[] key = ASCIIEncoding.ASCII.GetBytes(MD5(keyString));

            byte[] cipherTextBytes = Convert.FromBase64String(cypherText);
            if (key == null || key.Length <= 0)
                throw new ArgumentNullException("key");

            var ivStringBytes = ASCIIEncoding.ASCII.GetBytes(MD5(MD5(keyString)));

            var engine = new RijndaelEngine(256);
            var blockCipher = new CbcBlockCipher(engine);
            var cipher = new PaddedBufferedBlockCipher(blockCipher, new ZeroBytePadding());
            var keyParam = new KeyParameter(key);
            var keyParamWithIV = new ParametersWithIV(keyParam, ivStringBytes, 0, ivStringBytes.Length);
            cipher.Init(false, keyParamWithIV);
            var outputBytes = new byte[cipher.GetOutputSize(cipherTextBytes.Length)];
            var length = cipher.ProcessBytes(cipherTextBytes, outputBytes, 0);
            length += cipher.DoFinal(outputBytes, length);
            var resultText = Encoding.UTF8.GetString(outputBytes, 0, length);
            return resultText;
        }

I was cautioned that AES should be preferred over Rijndael with 256 bits block size. With that in mind I tried to write the decrypt method using AES but I could not succeed. It is not throwing any error but returning some garbage text.

 public static string DecryptStringFromAES(string cypherText, string keyString)
        {
            byte[] key = ASCIIEncoding.ASCII.GetBytes(MD5(keyString));
            byte[] cipherText = Convert.FromBase64String(cypherText);

            if (key == null || key.Length <= 0)
                throw new ArgumentNullException("key");

            string plaintext;
            using (var aes = Aes.Create())
            {
                aes.BlockSize = 128;
                aes.Key = key;
                aes.Mode = CipherMode.CBC;
                aes.Padding = PaddingMode.Zeros;
                aes.IV = new byte[16];

                ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
                using (var msDecrypt = new MemoryStream(cipherText))
                using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                using (var srDecrypt = new StreamReader(csDecrypt))
                    plaintext = srDecrypt.ReadToEnd();
            }
            return plaintext;
        }

I am not an expert in Cryptography and I don't really know what is wrong in the above code. My job demanded this task to decrypt some encrypted information from Active Directory. Encryption is done by some other process and I can't share the encryption key and don't have test code as we don't have a test environment.

Appreciate if someone could look at the code and see if I messed up anything with that code and suggest any correction that could possibly fix the issue. Thanks in advance.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
rednerus
  • 401
  • 2
  • 9
  • 21
  • 1
    First of all: Rijndael with a 256 bits blocksize and AES (which is a subset of Rijndael with a 128 bits blocksize) are different algorithms, s. [here](https://stackoverflow.com/a/748645/9014097) for more details. You can't just change the decryption without changing the encryption. AES is the standard and not Rijndael, so AES should be preferred (but of course on both sides). Regarding the posted code: Wrong is that not the IV of the encryption is used, but a random IV. – Topaco Apr 06 '22 at 06:16
  • Padding with zeros is also insecure and should be avoided. And you should really improve your code quality regarding encoding. Your string encoding decoding is a major source of problem. For example an MD5 should never return a String, just let it return byte[] and use it properly. – Robert Apr 06 '22 at 07:40

0 Answers0