-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
When using AesCng with the CipherMode in CFB mode with a persisted CNG key, it appears that CFB8 is always used for the actual feedback size, even if FeedbackSize is set to 128.
Steps to reproduce:
Run the following snippet (with package reference to System.Security.Cryptography.Cng):
using System;
using System.Security.Cryptography;
// Create the key
CngAlgorithm aesAlgorithm = new CngAlgorithm("AES");
CngKeyCreationParameters opts = new CngKeyCreationParameters
{
ExportPolicy = CngExportPolicies.AllowPlaintextExport,
};
try
{
CngKey key = CngKey.Create(aesAlgorithm, "potato-key", opts);
key.Dispose();
}
catch (CryptographicException ce) when ((uint)ce.HResult == 0x8009000F)
{
// Don't worry about the key already existing.
}
static byte[] Encrypt(Aes aes, int feebackSizeBits)
{
aes.FeedbackSize = feebackSizeBits;
aes.Mode = CipherMode.CFB;
aes.Padding = PaddingMode.PKCS7;
aes.IV = new byte[aes.BlockSize / 8];
var input = new byte[] { 1, 2, 3, 4, 5 };
using ICryptoTransform transform = aes.CreateEncryptor();
byte[] result = transform.TransformFinalBlock(input, 0, input.Length);
return result;
}
AesCng cng = new AesCng("potato-key");
Aes aes = Aes.Create();
aes.Key = cng.Key;
byte[] cng8Result = Encrypt(cng, 8);
byte[] aes8Result = Encrypt(aes, 8);
Console.WriteLine("CNG 8: " + Convert.ToHexString(cng8Result));
Console.WriteLine("AES 8: " + Convert.ToHexString(aes8Result));
byte[] cng128Result = Encrypt(cng, 128);
byte[] aes128Result = Encrypt(aes, 128);
Console.WriteLine("CNG128: " + Convert.ToHexString(cng128Result));
Console.WriteLine("AES128: " + Convert.ToHexString(aes128Result));It will produce an output that looks something like this. The output will be different from this one since the code generates a key, but this illustrates the pattern.
CNG 8: 3CF1DB609559
AES 8: 3CF1DB609559
CNG128: 3CF1DB6095538DD2611E7FBC7531083C
AES128: 3CD079280665EE399880253D9B40D035
AesCng and Aes.Create() agree for CFB8. However for CFB128, the results do not agree. The CNG128 line differs from the AES128 line. In this case, the CNG128 line's first 5 bytes match the result of CNG8, indicating CFB8 was actually used for the encryption, however it was padded as if CFB128 were used.
Configuration
Occurs in .NET 5 and main on all versions of Windows.
Other information
I suspect this is also the same for TripleDESCng with CFB64.