0

I wanna store an encrypted string inside a SQL Database as a byte array and I can't figure out what I'm doing wrong. The code is this:

    private void loginBtn_Click(object sender, EventArgs e)
    {
        try
        {
            string password = passwordBox.Text.ToString();

            using (Aes algorithm = Aes.Create())
            {
                byte[] encryptedPassword = EncryptString(password, algorithm.Key, algorithm.IV);

                string roundTrip = DecryptString(encryptedPassword, algorithm.Key, algorithm.IV);

                MessageBox.Show("Encrypted Password: " + encryptedPassword.ToString() + '\n' + "Round Trip: " + roundTrip.ToString());
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

And the code used for the 'EncryptString' and 'DecryptString' is the one from Microsoft's Aes Class Reference (the Example situated at the end of the page).

I executed my code and all it gives me in a Message Box is this:

Encrypted Password: System.Byte[]

Round Trip: (empty space)

    static byte[] EncryptString(string str, byte[] key, byte[] IV)
    {
        if (str == null || str.Length <= 0)
            throw new ArgumentNullException("string");
        if (key == null || key.Length <= 0)
            throw new ArgumentNullException("key");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("IV");

        byte[] encrypted;

        using (Aes algorithm = Aes.Create())
        {
            algorithm.Key = key;
            algorithm.IV = IV;

            ICryptoTransform encryptor = algorithm.CreateEncryptor(algorithm.Key, algorithm.IV);

            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(str);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }

        return encrypted;
    }

    static string DecryptString(byte[] cipher, byte[] key, byte[] IV)
    {
        if (cipher == null || cipher.Length <= 0)
            throw new ArgumentNullException("cipher");
        if (key == null || key.Length <= 0)
            throw new ArgumentNullException("key");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("IV");

        string decrypted;

        using (Aes algorithm = Aes.Create())
        {
            algorithm.Key = key;
            algorithm.IV = IV;

            ICryptoTransform decryptor = algorithm.CreateDecryptor(algorithm.Key, algorithm.IV);

            using (MemoryStream msDecrypt = new MemoryStream())
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                        decrypted = srDecrypt.ReadToEnd();
                    }
                }
            }
        }

        return decrypted;
    }

Can someone help me fix it, please?

P.S. The Text Box has the Password Char setted to *

Community
  • 1
  • 1
  • Works fine for me. Post your actual encrypt/decrypt code please. – Kevin Ford Oct 01 '17 at 11:22
  • This program works correctly for me too - with `string password = "ABCD"`, roundTrip alco contains "ABCD". What did you try as a password? Did you do any modifications to `EncryptString` and `DecryptString` methods from Microsoft's example? – Ňuf Oct 01 '17 at 11:23
  • You will see it better if you change your message line to MessageBox.Show("Encrypted Password: " + Encoding.ASCII.GetString(encryptedPassword) + '\n' + "Round Trip: " + roundTrip); or something like (possibly UTF instead of ACII, depends on your character set). – Kevin Ford Oct 01 '17 at 11:25
  • Then `passwordBox.Text` is probably empty. Set breakpoints, step through your code, inspect your variables. – CodeCaster Oct 01 '17 at 11:47
  • @KevinFord I posted my code. – DannyDSB Official Oct 01 '17 at 16:25
  • That stops it working, now we have something to look at ;-) – Kevin Ford Oct 01 '17 at 18:28

1 Answers1

1

In DecryptString method, you forgot to pass cipher parameter to constructor of msDecrypt memory stream as an input, thus method actually deciphers empty input stream, so result is empty too.

Line

using (MemoryStream msDecrypt = new MemoryStream())

should actually be:

using (MemoryStream msDecrypt = new MemoryStream(cipher))

and then everything works fine.

Ňuf
  • 6,027
  • 2
  • 23
  • 26
  • I just found the same thing! That'll teach me to keep reading :-) – Kevin Ford Oct 01 '17 at 18:35
  • Thank you very much. Now I know that I have to pay more attention to code examples. You fixed it, I cannot believe that it was hiding so good. Now, I have another little problem. If I use Encoding.ASCII.GetBytes(here are 64 characters); as key and Encoding.ASCII.GetBytes(here are 32 characters); as IV, it gives me the error: "The specified key is not a valid size for this algorithm. ". Do you know how should I do this? I tried to modify the BlockSize of the Aes Algorithm but it won't work, instead, it gives me the same error message. Thanks again! – DannyDSB Official Oct 01 '17 at 18:57
  • There are only 3 variants of AES: AES-128, AES-192 and AES-256. So **key size** must be 128 bits (16 bytes), 192 bits (24 bytes) or 256 bits (32 bytes). You can get valid key sizes from [LegalKeySizes](https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.symmetricalgorithm.legalkeysizes?view=netframework-4.7) property. Also all AES variants requires **block size** of 128 bits (16 bytes) as you can see in [LegalBlockSizes](https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.symmetricalgorithm.legalblocksizes?view=netframework-4.7) property. – Ňuf Oct 01 '17 at 19:47