Open beta-tester opened 1 year ago
Tagging subscribers to this area: @dotnet/area-system-security, @bartonjs, @vcsjones See info in area-owners.md if you want to be subscribed.
Author: | beta-tester |
---|---|
Assignees: | - |
Labels: | `area-System.Security` |
Milestone: | - |
.NET defaults to a feedback size of 8, not 128, for AES. .NET also requires you to pad to the feedback size, but you can work around that with padding and just add it and remove as needed. Here is an example:
using System.Security.Cryptography;
test();
void test()
{
var key = new byte[16];
var iv = new byte[16];
var text = new char[6];
byte[] encrypted, decrypted;
using (var crypto = Aes.Create())
{
crypto.Key = key;
encrypted = crypto.EncryptCfbTruncated(iv, System.Text.Encoding.ASCII.GetBytes(text));
decrypted = crypto.DecryptCfbTruncated(iv, encrypted);
}
// dump
for (int i = 0; i < encrypted.Length; i++)
Console.Write($"0x{encrypted[i]:X02}, ");
Console.WriteLine();
for (int i = 0; i < decrypted.Length; i++)
Console.Write($"0x{decrypted[i]:X02}, ");
Console.WriteLine();
}
static class Extensions
{
public static byte[] EncryptCfbTruncated(this Aes aes, byte[] iv, byte[] data)
{
byte[] result = aes.EncryptCfb(data, iv, PaddingMode.Zeros, feedbackSizeInBits: 128);
return result[0..data.Length];
}
public static byte[] DecryptCfbTruncated(this Aes aes, byte[] iv, byte[] data)
{
int size = aes.GetCiphertextLengthCfb(data.Length, PaddingMode.Zeros, feedbackSizeInBits: 128);
byte[] tempBuffer = new byte[size];
data.AsSpan().CopyTo(tempBuffer);
byte[] decrypted = aes.DecryptCfb(tempBuffer, iv, PaddingMode.Zeros, feedbackSizeInBits: 128);
return decrypted[0..data.Length];
}
}
That roundtrips the data and outputs what the other platforms output.
thank you for the quick workaround.
i never expected that CFB needs padding and truncating to get the same behavior as the other language implementations gives. looks odd to me.
i think i have an issue with the workaround.
as far as i understand the methods EncryptCfb()
and DecryptCfb()
they can only process the complete data in one pass.
is there a possibility to Read/Write small chunks of data and decrypt/encrypt them and continue/update the decryption/encryption of further chunks like the update in the other language implementations (like a big data stream)?
they can only process the complete data in one pass. is there a possibility to Read/Write small chunks of data and decrypt/encrypt them and continue/update the decryption/encryption of further chunks like the update in the other language implementations (like a big data stream)?
Indeed, those are the "one shots". For incremental work, your initial example of using CreateTransfom
+ TransformBlock
+ TransformFinalBlock
would do the trick.
For incremental work, your initial example of using CreateTransfom + TransformBlock + TransformFinalBlock would do the trick.
Uhh, that job is way more complicated than expected in C#
.
specially for me who is just using the Aes
library and has no deep background what is going on under the hood.
the MCU encrypts data in an stacked two pass aes_cfb_128
method, where in between the two passes the encrypted data is XOR
'ed depending on small chunks of previous encrypted data of the first pass.
(i think it is done to obscure the weaker aes_cfb_128
method - but i have to use it as is to be compatible with other units of the same kind)
now i have to keep track of the padding / truncating to be able to decrypt the two stacked encryption passes with the embedded picking the small chunks of XOR
dependencies to undo the XOR
'ing in between.
the small chunks are not aligned to the padding needed by the C#
implementation. the data stream also isn't aligned/padded.
it is so much easier in MBEDTLS
and Python
to do so without the need of keep track of padding or truncating the encrypted data.
is there a plan to get rid of the need of manually padding/truncating for the user of the Aes
CFB
library?
or are there other libraries available for C# .NET >=6.0 those are more like the other language libraries?
Description
hi, there is an issue with encrypting / decrypting AES CFB 128. (System.Security.Cryptography.Aes, CipherMode.CFB, KeySize = 128) on an ESP32 micro controller i am using the
MBEDTLS
library to encrypt / decrypt data in AES CFB 128. i can encrypt / decrypt the same data on a PC by using python3. but when i try to encrypt / decrypt the data on a PC by using .NET i get corrupt data.i am using VisualStudio 2022 Community .NET 6.0 / .NET 7.0
in the test below, i get the following hex dump for encryption:
0x66, 0x16, 0xF9, 0x2E, 0x42, 0xA8,
, C#.0x66, 0xE9, 0x4B, 0xD4, 0xEF, 0x8A,
, Python.0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a,
, MBEDTLS (ESP32 / Arduino).Reproduction Steps
i am using the following code snips to reproduce the issue:
MBEDTLS (ESP32 / Arduino): hex dump:
0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a,
Python3.11 (PC / Linux, Windows) hex dump:
0x66, 0xE9, 0x4B, 0xD4, 0xEF, 0x8A,
C# (PC / Windows): hex dump:
0x66, 0x16, 0xF9, 0x2E, 0x42, 0xA8,
Expected behavior
the expected behavior is having same result under C# / Python / MBEDTLS:
0x66, 0xE9, 0x4B, 0xD4, 0xEF, 0x8A,
, C#.0x66, 0xE9, 0x4B, 0xD4, 0xEF, 0x8A,
, Python.0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a,
, MBEDTLS (ESP32 / Arduino).Actual behavior
actual behavior in C# is having different result compared to Python and MBEDTLS results:
0x66, 0x16, 0xF9, 0x2E, 0x42, 0xA8,
, C#.0x66, 0xE9, 0x4B, 0xD4, 0xEF, 0x8A,
, Python.0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a,
, MBEDTLS (ESP32 / Arduino).Regression?
No response
Known Workarounds
No response
Configuration
Other information
No response