-2

I have the sample code using C# .NET Rijndael cryptography encryption, which can decrypt ciphertext "FGgsUwQ1gToX40dfgdfgfdgdfgdfCzEr3wOenxTPMN9jJC" to plain "75.117.87.87".

enter image description here

I have tried to write the reserved method to encrypt plain text "75.117.87.87" to "FGgsUwQ1gToX40dfgdfgfdgdfgdfCzEr3wOenxTPMN9jJC" but not successful (encrypted text is not as same as expectation - , but the result likes in the attached image . Please help me, thank you.

static int Main(string[] args)
    {
        Decrypt();
        Console.WriteLine("########################");
        Console.WriteLine("########################");
        Encrypt();
        Console.ReadLine();
        return 0;
    }
public static void Decrypt()
    {
        string ciphertext = "LkbsUwQ1gToX40dYXizgc0BCCCzEr3wOenxTPMN9jJC";
        string secretkey = "11111111";
        string saltkey = "thekey";

        string result =  rijndaelDecrypt(ciphertext, secretkey, saltkey);

        Console.WriteLine("Cipher text: " + ciphertext);
        Console.WriteLine("Decrypted text: " + result);
        return;
    }
public static string  rijndaelDecrypt(string ciphertext, string secretkey, string saltkey)
    {
        if (string.IsNullOrEmpty(ciphertext))
        {
            return null;
        }
        if (string.IsNullOrEmpty(secretkey))
        {
            return null;
        }

        ciphertext = "EAAAA" + ciphertext;

        RijndaelManaged rijndaelManaged = null;
        string result = null;
        try
        {
            Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(secretkey, Encoding.ASCII.GetBytes(saltkey));
            byte[] buffer = Convert.FromBase64String(ciphertext);
            MemoryStream memoryStream = new MemoryStream(buffer);
            rijndaelManaged = new RijndaelManaged();
            rijndaelManaged.Key = rfc2898DeriveBytes.GetBytes(rijndaelManaged.KeySize / 8);
            rijndaelManaged.IV = rb(memoryStream);
            ICryptoTransform transform = rijndaelManaged.CreateDecryptor(rijndaelManaged.Key, rijndaelManaged.IV);
            CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read);
            StreamReader streamReader = new StreamReader(cryptoStream);
            result = streamReader.ReadToEnd();
        }
        catch (Exception)
        {
            if (rijndaelManaged != null)
            {
                rijndaelManaged.Clear();
            }
            return null;
        }
        finally
        {
            if (rijndaelManaged != null)
            {
                rijndaelManaged.Clear();
            }
        }
        return result;
    }
public static void Encrypt()
    {
        string ciphertext = "75.117.87.87";
        string secretkey = "1111111";
        string saltkey = "thekey";
        string result;
        RijndaelManaged rijndaelManaged = new RijndaelManaged();

        Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(secretkey, Encoding.ASCII.GetBytes(saltkey));

        rijndaelManaged.Key = rfc2898DeriveBytes.GetBytes(rijndaelManaged.KeySize / 8);

        byte[] buffer = EncodeToBytes(ciphertext);
        MemoryStream memoryStream = new MemoryStream(buffer);
        rijndaelManaged.IV = rfc2898DeriveBytes.GetBytes(rijndaelManaged.BlockSize / 8);
        //rijndaelManaged.IV = rb(memoryStream);

        ICryptoTransform transform = rijndaelManaged.CreateEncryptor(rijndaelManaged.Key, rijndaelManaged.IV);
        CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read);
        StreamReader streamReader = new StreamReader(cryptoStream);
        result = streamReader.ReadToEnd();


        var encryptor = rijndaelManaged.CreateEncryptor(rijndaelManaged.Key, rijndaelManaged.IV);
        var msEncrypt = new MemoryStream();

        using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
        using (var swEncrypt = new StreamWriter(csEncrypt))
            swEncrypt.Write(result);

        result = Convert.ToBase64String(msEncrypt.ToArray());

        Console.WriteLine("Plain text: " + ciphertext);
        Console.WriteLine("Encrypted text: " + result);
        return;
    }
private static byte[] rb(Stream s)
    {
        byte[] array = new byte[4];
        if (s.Read(array, 0, array.Length) != array.Length)
        {
            return null;
        }
        byte[] array2 = new byte[BitConverter.ToInt32(array, 0)];
        if (s.Read(array2, 0, array2.Length) != array2.Length)
        {
            return null;
        }
        return array2;
    }
 private static byte[] EncodeToBytes(string str)
    {
        byte[] bytes = new byte[str.Length * sizeof(char)];
        System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
        return bytes;
    }
  • I don't see any trials in your code :) – Laurent Lequenne Jun 26 '17 at 13:24
  • I don't see any attempt of encryption methods. When asking "why is X not working?" make sure to at least show code of X. It's even better when you explain what you tried. – Domi Jun 26 '17 at 13:25
  • @domi1819 : I have updated Encrypting method and image, thank you for your attention! I think the problem is Initialization vector in Encryption method – Antony Sam Jun 26 '17 at 13:51

1 Answers1

0

You are using different IVs. For your decryption method, you are using the base64 decoded ciphertext:

byte[] buffer = Convert.FromBase64String(ciphertext);
MemoryStream memoryStream = new MemoryStream(buffer);
rijndaelManaged.IV = rb(memoryStream);

For your encryption method, you are deriving it from the password using PBKDF2 (Rfc2898DeriveBytes) which is the right way to do if and only if you construct your Rfc2898DeriveBytes with a random salt. Alternatively, you can use a RNGCryptoServiceProvider to get a completely random IV.

rijndaelManaged.IV = rfc2898DeriveBytes.GetBytes(rijndaelManaged.BlockSize / 8);

From a security perspective, you should use a random salt for deriving your key / IV and prepend it to the ciphertext when encrypting. For decrypting, you should cut it off again (and use it for deriving the decryption key / IV).

Domi
  • 272
  • 1
  • 3
  • 9
  • 1
    I downvoted because deriving an IV from a KDF is **not** what you are meant to do, since you'll end up with a static IV when encrypting under the same key. IVs should always be randomly generated with a CSPRNG. – Luke Joshua Park Jun 26 '17 at 14:21
  • @LukePark I'd downvote your comment if I could, because deriving an IV from KDF is good when using a random salt. (That's why I put the security advice regarding random salt which you should always do) – Domi Jun 26 '17 at 14:26
  • No, it is not. Using the same IV and same key for more than one encryption operation means that the IV is not unpredictable. This is basic knowledge. – Luke Joshua Park Jun 26 '17 at 14:28
  • @LukePark Please think before commenting. Using different salts for KDF results in completely different outputs, therefore you are not using the same key / IV twice. – Domi Jun 26 '17 at 14:30
  • 1
    I think you misunderstand. I am not arguing that the IV generated is not a suitable one. I am against your blanket statement "For your encryption algorithm, you are deriving it from the password... Which is the right way to do.". This isn't the right way to do and is misleading. In this case, under these specific circumstances, it produces an acceptable result. However, changing the code to re-use an AES instance instantly introduces problems. If the code simply randomly generated the IV each time, it would be impossible to introduce errors by changing the code in other areas. – Luke Joshua Park Jun 26 '17 at 14:34
  • 1
    More specifically, recall that the point of StackOverflow is to help others as much as the OP. What if someone less versed in cryptography were to read your advice about deriving an IV from the same KDF as the key? Very misleading. I hope you understand. – Luke Joshua Park Jun 26 '17 at 14:36
  • 1
    @domi1819 Simply just use a CSPRNG to get the IV. – zaph Jun 26 '17 at 14:38
  • @all thank you for your discussion. in my Dycryption: inline `ciphertext = "EAAAA" + ciphertext; byte[] buffer = Convert.FromBase64String(ciphertext); MemoryStream memoryStream = new emoryStream(buffer); rijndaelManaged.IV = rb(memoryStream);` in my Encrypt: How to "45.119.81.82" => corresponding IV????? – Antony Sam Jun 26 '17 at 15:21