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

1

17

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?

Dupuis answered 8/10, 2018 at 9:48 Comment(5)
Do you really need a block size different from 128? It's not linked to the key size. Key size 256 works perfectly with block size 128. If the encryption is supposed to be compatible with AES, the block size must be 128 and the key size either 128, 192 or 256.Anguilla
@Anguilla Yes, I have to use 256 for block size. Encrypted data is going to sent to third-party service and I've got an IV from the third-party with 32 lengths.Dupuis
See my updated answer.Inflame
You want Rijndael with a 256-bit block size, but you use the variable name aes to hold it? If that isn't intentional obfuscation then you are confused.Hales
It's not an intentional obfuscation, nor a confusion. I know what they are and their differences. I just copied the sample code the third-party company provided. But it's a good suggestion to change the names.Dupuis
I
16

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);
Inflame answered 8/10, 2018 at 10:23 Comment(2)
"Rijndael" as originally specified allowed various block sizes. It's when it was adopted as AES that the block size restriction was added in that incarnation. So you definitely shouldn't be able to find something claiming to implement AES that offers variable block sizes.Inch
For anyone who is using this code to decrypt, cipher.Init should be called with falsePreemption

© 2022 - 2024 — McMap. All rights reserved.