16

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?

thirdDeveloper
  • 855
  • 1
  • 10
  • 30
  • 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. – Codo Oct 08 '18 at 11:06
  • @Codo 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. – thirdDeveloper Oct 08 '18 at 11:18
  • See my updated answer. – Access Denied Oct 08 '18 at 13:18
  • 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. – President James K. Polk Oct 08 '18 at 17:21
  • 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. – thirdDeveloper Oct 09 '18 at 07:58

1 Answers1

15

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);
Access Denied
  • 8,723
  • 4
  • 42
  • 72
  • 5
    "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. – Damien_The_Unbeliever Oct 08 '18 at 10:48
  • 4
    For anyone who is using this code to decrypt, `cipher.Init` should be called with `false` – Lourens Mar 13 '20 at 13:43