Closed gcatwork closed 9 months ago
Version 2.0.0 only encrypts string
properties into Base64 strings. Version 3+ adds the supports for both string and byte arrays.
Also, using data annotation should not break your code since we just added the fluent notation in version 4.X.
Below the code of the encrypt method from version 2.0.0 :
https://github.com/Eastrall/EntityFrameworkCore.DataEncryption/blob/68f1a9dc04f3449f51aaac1196eb9f66ffb75745/src/EntityFrameworkCore.DataEncryption/Providers/AesProvider.cs#L58-L82
I notice that the IV is also encrypted along the data. (16 first bytes) This practice has been deprecated. You can refer to this issue : https://github.com/Eastrall/EntityFrameworkCore.DataEncryption/issues/46#issuecomment-1401939203 to use a provider using dynamic IV.
thanks - from what I see the change below would suffice
EncryptionConverter.cs
private static TModel Decrypt<TInput, TOupout>(TProvider input, IEncryptionProvider encryptionProvider, StorageFormat storageFormat)
{
Type destinationType = typeof(TModel);
byte[] inputData;
if (storageFormat is StorageFormat.Default or StorageFormat.Base64)
// ORIG
//inputData = Convert.FromBase64String(input.ToString());
// ALTERNATIVE
{
var strToDescrypt = input.ToString();
inputData = System.Text.Encoding.UTF8.GetBytes(strToDescrypt);
}
else
inputData = input as byte[];
byte[] decryptedRawBytes = encryptionProvider.Decrypt(inputData);
object decryptedData = null;
if (destinationType == typeof(string))
{
decryptedData = Encoding.UTF8.GetString(decryptedRawBytes).Trim('\0');
}
else if (destinationType == typeof(byte[]))
{
decryptedData = decryptedRawBytes;
}
return (TModel)Convert.ChangeType(decryptedData, typeof(TModel));
}
Noting our decryption provider could then be adjusted to the following :
public byte[] Decrypt(byte[] input)
{
var protector = _provider.CreateProtector(Purpose);
var inputStr = System.Text.Encoding.UTF8.GetString(input);
var decryptedString = protector.Unprotect(inputStr);
var decrtypedByteArray = System.Text.Encoding.UTF8.GetBytes(decryptedString);
return decrtypedByteArray;
}
Any suggestions regarding the following. Have migrated a .NET API layer from .NET v5 to v7. Key package versions:
Creating new records and reading (encrypting / decrypting) on newer versions (.NET 7) are fine.
Trying to decrypt data columns (nvarchar(max)) from records in the database from the .NET v5 versions, give a "not a valid Base-64 string". I note that the encrypted string in the database from such earlier version (.NET 5) created record has a length of 155 which is suspect. However this was being decrypted ok with DataEncryption v2.0.0 (.NET v5)
Extract from exception:
Also I noted that I had to move from using a decorator to using fluent, and pass in the StoreFormat.Base64 option. (e.g. builder.Property(x => x.DateOfBirth).IsRequired().IsEncrypted(StorageFormat.Base64);). If I change this setting to binary I get below:
The newer custom enyption provider "Decrypt" method had to change to use byte arrays instead of strings too FYI.
Any thoughts/direction?