Search code examples
c#encryption.net-corerijndael.net-core-2.1

How to use Rijndael algorithm with 256 long block size in dotnet core 2.1


I'm trying to encrypt a string with RijndaelManaged in order to send it to a third-party service. I've implemented the procedure in older versions of .Net framework (4.5, 4.6.x) like below:

RijndaelManaged rm= new RijndaelManaged();
rm.KeySize = 256;
rm.BlockSize = 256;//causes exception in dotnet core 2.1
rm.Padding = PaddingMode.PKCS7;
rm.Key = Convert.FromBase64String(this.Key);
rm.IV = Convert.FromBase64String(this.IV);

var encrypt = rm.CreateEncryptor(rm.Key, rm.IV);

According to documentation, RijndaelManaged class can be used with BlockSize = 256. But, when the code is running in dotenet core 2.1, an exception thrown:

System.PlatformNotSupportedException: BlockSize must be 128 in this implementation. at System.Security.Cryptography.RijndaelManaged.set_BlockSize(Int32 value)

UPDATE

Thanks to @Access-Denied's response, according to this, I've noticed that it may be a mistake in dotnet core documentation and I can't use a 256 long BlockSize with RijndaelManaged class. As I mentioned, encrypted data is going to be sent to a third-party service. I have to use Rijndael with a 32 long IV. How can I handle that?


Solution

  • The best documentation is a source code. According to their source code only 128 is supported:

    public override int BlockSize
    {
        get { return _impl.BlockSize; }
        set
        {
            Debug.Assert(BlockSizeValue == 128);
    
            //Values which were legal in desktop RijndaelManaged but not here in this wrapper type
            if (value == 192 || value == 256)
                throw new PlatformNotSupportedException(SR.Cryptography_Rijndael_BlockSize);
    
            // Any other invalid block size will get the normal "invalid block size" exception.
            if (value != 128)
                throw new CryptographicException(SR.Cryptography_Rijndael_BlockSize);
        }
    }
    

    Use BouncyCastle.NetCore. There is a code snippet available at the following link:

    var keyBytes = password.GetBytes(Keysize / 8);
    var engine = new RijndaelEngine(256);
    var blockCipher = new CbcBlockCipher(engine);
    var cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
    var keyParam = new KeyParameter(keyBytes);
    var keyParamWithIV = new ParametersWithIV(keyParam, ivStringBytes, 0, 32);
    
    cipher.Init(true, keyParamWithIV);
    var comparisonBytes = new byte[cipher.GetOutputSize(cipherTextBytes.Length)];
    var length = cipher.ProcessBytes(cipherTextBytes, comparisonBytes, 0);
    cipher.DoFinal(comparisonBytes, length);