Search code examples
flutterdartencryption

What is the equivalent of C# Rijndael Key and IV in dart?


I have an encryption function in C# and i wish to copy it to dart:

C# (The part of code i cant reproduce in dart):

private RijndaelManaged myRijndael = new RijndaelManaged();
public ClsCrypto(string strPlainText)
{
string strIV = "$@A@B@_3CP$Y$T2M";

myRijndael.IV = Encoding.UTF8.GetBytes(strIV);
myRijndael.Key = Encoding.UTF8.GetBytes("$@J@Y@3NT3RPRI$3R3$OURC3PL@NNING");
byte[] originalBytes = new System.Text.UTF8Encoding().GetBytes(strPlainText);

ICryptoTransform transform = myRijndael.CreateEncryptor();
byte[] encryptedText = transform.TransformFinalBlock(originalBytes, 0, originalB
ytes.Length);
return Convert.ToBase64String(encryptedText);
}

I couldn't find resources on the web, I used the "encrypt.dart" package to do this:

    final key = Key.fromUtf8("\$@J@Y@3NT3RPRI\$3R3\$OURC3PL@NNING");
    final iv = IV.fromUtf8("\$@A@B@_3CP\$Y\$T2M");

    final encrypter = Encrypter(AES(key));
    final encrypted = encrypter.encrypt(plainText, iv: iv);

but I couldn't get the same encryption.

My code and result :

 String strIV = "\$@J@Y@_3RP\$Y\$T3M";
    final plainText = 'CCCC-1111-CCCC-2222-CCCC-3333-CCCC';
    final key = Key.fromUtf8(String.fromCharCodes(utf8.encode("\$@J@Y@3NT3RPRI\$3R3\$OURC3PL@NNING")));
    final iv = IV.fromUtf8(String.fromCharCodes(utf8.encode(strIV)));

    final encrypter = Encrypter(AES(key));
    final encrypted = encrypter.encrypt(plainText, iv: iv);
    print("encrypted : ${encrypted.base64}");

result : encrypted :

UwQqA5DjJ7xO3POMpmyQZxINEGDM9ImcEgrC5M8pF2hiFy4CkCrbY6QBdM7EbbuR

C#:

using System;
using System.Security.Cryptography;
using System.Text;
namespace ConsoleApp3
{

public class ClsCrypto
{ 
private RijndaelManaged myRijndael = new RijndaelManaged();

public static void Main(){
        ClsCrypto cs = new ClsCrypto("$@J@Y@_3RP$Y$T3M");
         cs.Encrypt("CCCC-1111-CCCC-2222-CCCC-3333-CCCC");
        }
public ClsCrypto(string strIV)
{
}
public void Encrypt(string strPlainText)
{
String strIV = "$@J@Y@_3RP$Y$T3M"; //Default IV
myRijndael.IV = Encoding.UTF8.GetBytes(strIV);
myRijndael.Key = Encoding.UTF8.GetBytes("$@J@Y@3NT3RPRI$3R3$OURC3PL@NNING");
byte[] originalBytes = new System.Text.UTF8Encoding().GetBytes(strPlainText);
ICryptoTransform transform = myRijndael.CreateEncryptor();
byte[] encryptedText = transform.TransformFinalBlock(originalBytes, 0, originalBytes.Length);
//return Convert.ToBase64String(encryptedText);
Console.WriteLine(Convert.ToBase64String(encryptedText));
}
}
}

result :

26CxCs5A7c7Sk5+0/hQ300vkHsCuRPXyACbrcRxyeCBWwAK9TCOLdkDHvBaLJXYH


Solution

  • As I already mentioned in the comment, the encrypt package uses SIC aka CTR as the default mode (s. encrypt 5.0.3, sec. Usage - Modes of operation), while in the C# code CBC is applied (by default).
    Since the C# code is the reference, CBC must also be used in the Dart code so that both codes are compatible. This requires the following change:

    final encrypter = Encrypter(AES(key, mode: AESMode.cbc));
    

    With this, both codes for the same plaintext, key and IV generate the same ciphertext.


    Security:
    The use of a static IV is a vulnerability (better: apply a randomly generated IV).
    In addition, the UTF-8 encoding of the key indicates a passphrase, which is also a vulnerability due to the generally low entropy (better: use a key derivation function in conjunction with a randomly generated salt to derive a key from the passphrase).
    Salt and IV are not secret and are passed to the decrypting side along with the ciphertext (usually concatenated).
    With regard to the C# code, also be aware that RijndaelManaged is obsolete.