What should I do with the Encrypt code of this Decrypt code?

patrick

Well-known member
Joined
Dec 5, 2021
Messages
305
Programming Experience
1-3
Hello.
Decrypt code.
What should I do with the Encrypt code of this Decrypt code?
Please Help me


C#:
        public string Decrypt(string data)
        {
          
                using (RijndaelManaged rijndael = new RijndaelManaged())
                using (Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(_Key, Convert.FromBase64String(data).Take(16).ToArray()))
                using (ICryptoTransform decryptor = rijndael.CreateDecryptor(rfc2898.GetBytes(32), rfc2898.GetBytes(16)))
                using (MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(data).Skip(16).ToArray()))
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                using (StreamReader streamReader = new StreamReader(cryptoStream))
                    data = streamReader.ReadToEnd();


            return data;
        }
 
What do you mean by "what should I do with [it]"? Are you asking us how to write code to encrypt data that can then be decrypted by that code? Assuming so, have you applied some logic to the problem to see what you can do for yourself? What are the steps that code performs? Code to do the opposite would perform the opposite steps, would it not? Where that code calls rijndael.CreateDecryptor, would it surprise you to learn that that type has a CreateEncryptor method? Rather than just asking us to write your code for you (assuming that's even what you're doing) make what efforts you can for yourself first, then show us what you've done and tell us where you're actually stuck.

By the way, that RijndaelManaged class is obsolete and the documentation explicitly states that you should use a different class.
 
The Encrypt code is being written based on the attached Decrypt code.


This Encrypt code does not work well What's wrong with Encrypt?
Please help me

C#:
 public string Encrypt(string data)
        {
            Byte[] pBlock = Encoding.Unicode.GetBytes(data);
            string org = Convert.ToBase64String(pBlock);
            byte[] plainBytes = Encoding.Unicode.GetBytes(org);


            RijndaelManaged rijndael = new RijndaelManaged();
            var rfc2898 = new Rfc2898DeriveBytes(_Key, plainBytes);
            var ms = new MemoryStream();
            using (var cs = new CryptoStream(ms, rijndael.CreateEncryptor(rfc2898.GetBytes(32), rfc2898.GetBytes(16)), CryptoStreamMode.Write))
            {
                cs.Write(plainBytes, 0, plainBytes.Length);
            }
                     
            return Convert.ToBase64String(ms.ToArray());
        }
 
What does "does not work well" actually mean? What actually happened when you ran the code in the debugger? Please stop trying to get away with providing as little information as possible. We would like to help but we shouldn't have to work out things that you should already know. Please provide a FULL and CLESAR explanation of the problem, which includes exactly what you're trying to achieve, how you're trying to achieve it, what happens when you try and how that differs from your expectations. If you can't explain those things then it suggests that you haven't actually tried to understand the problem for yourself yet anyway.

In this specific case, I would suggest that such an explanation would involve listing the steps that the decryption code is performing and exactly how you're implementing the inverse operations in the encryption code. If you don't know clearly what the decryption code is doing, there's little point going further than that, to begin with at least. Part of solving problems is working out where exactly the problem is. Rushing off into later steps when you haven't established that the earlier steps are correct is not conducive to doing that.
 
C#:
public string Encrypt(string data)
        {
            string sta = ConvertToBASE64(data);
            byte[] StrByte = Encoding.Unicode.GetBytes(sta);

                using (RijndaelManaged rijndael = new RijndaelManaged())
                using (Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(_Key, StrByte.Take(16).ToArray()))
                using (ICryptoTransform encryptor = rijndael.CreateEncryptor(rfc2898.GetBytes(32), rfc2898.GetBytes(16)))
                using (MemoryStream memoryStream = new MemoryStream(StrByte.Skip(16).ToArray()))
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Read))
                using (StreamReader streamReader = new StreamReader(cryptoStream))
                    data = streamReader.ReadToEnd();

            return data;

        }


The Encrypt code is being written based on the attached Decrypt code.

This Encrypt code does not work well What's wrong with Encrypt?
Please help me
 
You have things backwards because you haven't analyzed what Decrypt does and reversed that. Also, opposite of StreamReader is StreamWriter, encryptor must write what decryptor can read.

In Decrypt method input data is a Base64 encoded string, which is decoded to bytes. First 16 bytes is salt for Rfc2898DeriveBytes (not encrypted), rest of bytes is an encrypted string.

Base64 encoding in Decrypt is first step, therefore it must be last step in a Encrypt. The Decrypt method is converting from Base64 twice different places, which it doesn't need to, and makes it more convoluted than it has to be. It would be better, and easier to read too, if Decrypt was written like this:
C#:
public string Decrypt(string data)
{
    var bytes = Convert.FromBase64String(data); // 16 bytes salt, rest encrypted string
  
    using (var rijndael = new RijndaelManaged())
    using (var rfc2898 = new Rfc2898DeriveBytes(_Key, bytes.Take(16).ToArray()))
    using (var decryptor = rijndael.CreateDecryptor(rfc2898.GetBytes(32), rfc2898.GetBytes(16)))

    using (var memory = new MemoryStream(bytes) { Position = 16 }) // skip 16 bytes salt
    using (var crypto = new CryptoStream(memory, decryptor, CryptoStreamMode.Read))
    using (var reader = new StreamReader(crypto))
    {
        return reader.ReadToEnd();
    }
}

So an Encrypt method must generate 16 bytes salt for Rfc2898DeriveBytes and add first in bytes to return (can write to directly to MemoryStream), encrypt a string as rest of bytes, and finally encode all bytes as Base64. Give it a go!
 
Since we are already using Decrypt, we need to write Encrypt code.
So the Decrypt code cannot be changed.
C#:
 public string Decrypt(string data)
        {
          
                using (RijndaelManaged rijndael = new RijndaelManaged())
                using (Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(_Key, Convert.FromBase64String(data).Take(16).ToArray()))
                using (ICryptoTransform decryptor = rijndael.CreateDecryptor(rfc2898.GetBytes(32), rfc2898.GetBytes(16)))
                using (MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(data).Skip(16).ToArray()))
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                using (StreamReader streamReader = new StreamReader(cryptoStream))
                    data = streamReader.ReadToEnd();


            return data;
        }
 
It wasn't changed, it was only made more clear the order of operations.
 
It wasn't changed, it was only made more clear the order of operations.

How do we convert the Decrypt chord to encrypt ?

C#:
public string Encrypt(string data)
        {
            string sta = ConvertToBASE64(data);
            byte[] StrByte = Encoding.Unicode.GetBytes(sta);

                using (RijndaelManaged rijndael = new RijndaelManaged())
                using (Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(_Key, StrByte.Take(16).ToArray()))
                using (ICryptoTransform encryptor = rijndael.CreateEncryptor(rfc2898.GetBytes(32), rfc2898.GetBytes(16)))
                using (MemoryStream memoryStream = new MemoryStream(StrByte.Skip(16).ToArray()))
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Read))
                using (StreamReader streamReader = new StreamReader(cryptoStream))
                    data = streamReader.ReadToEnd();

            return data;

        }

Is it correct to convert it like this?
 
Read post 6.
 
How do we convert the Decrypt chord to encrypt ?

As noted above, read post #6. It details what needs to be done to reverse the decryption process so that you derive the encryption process.
 
Read post 6.

Is it correct to convert it like this? I did as you explained. But it doesn't work

C#:
 public string Encrypt(string data)
        {
            Byte[] Bdata = Encoding.Unicode.GetBytes(data);         

            using (RijndaelManaged rijndael = new RijndaelManaged())
            using (Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(_Key, Bdata))
            using (ICryptoTransform Encryptor = rijndael.CreateEncryptor(rfc2898.GetBytes(32), rfc2898.GetBytes(16)))
            using (MemoryStream memoryStream = new MemoryStream(Bdata))
            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Read))
            using (StreamReader streamReader = new StreamReader(cryptoStream))
                data = streamReader.ReadToEnd();

            Byte[] pBlock = Encoding.Unicode.GetBytes(data);

            return Convert.ToBase64String(pBlock);
        }


C#:
 public string Encrypt(string data)
        {
            byte[] plainBytes = Encoding.Unicode.GetBytes(data);
            RijndaelManaged rijndael = new RijndaelManaged();

            var rfc2898 = new Rfc2898DeriveBytes(_Key, plainBytes);
            var ms = new MemoryStream();
            using (var cs = new CryptoStream(ms, rijndael.CreateEncryptor(rfc2898.GetBytes(32), rfc2898.GetBytes(16)), CryptoStreamMode.Write))
            {
                cs.Write(plainBytes, 0, plainBytes.Length);
            }
                       
            return Convert.ToBase64String(ms.ToArray());
        }
 
Last edited:
The second one is not too far off, except Salt must be 16 bytes, and you must add the Salt to memory stream before you add the encrypted string.

You can with ease generate a random salt with specified size with the Rfc2898DeriveBytes(string password, int saltSize) constructor. Salt should be random to improve security.
 
The second one is not too far off, except Salt must be 16 bytes, and you must add the Salt to memory stream before you add the encrypted string.

You can with ease generate a random salt with specified size with the Rfc2898DeriveBytes(string password, int saltSize) constructor. Salt should be random to improve security.


I modified it as you taught me. Rfc2898DeriveBytes was modified to 16 bytes.
However, decryption does not work.

decryption is fixed. Encrypt must be modified to fit decryption .

What's wrong with the code?
Please Help me.

C#:
 public string Encrypt(string data)
        {
            byte[] plainBytes = Encoding.Unicode.GetBytes(data);
            RijndaelManaged rijndael = new RijndaelManaged();

            var rfc2898 = new Rfc2898DeriveBytes(_Key, plainBytes.Take(16).ToArray());
            var ms = new MemoryStream();
            using (var cs = new CryptoStream(ms, rijndael.CreateEncryptor(rfc2898.GetBytes(32), rfc2898.GetBytes(16)), CryptoStreamMode.Write))
            {
                cs.Write(plainBytes, 0, plainBytes.Length);
            }
                     
            return Convert.ToBase64String(ms.ToArray());
        }
 
You didn't do this:
you must add the Salt to memory stream before you add the encrypted string

Also, using "plain bytes" here as salt is a very bad idea! You should see why.
 
Back
Top Bottom