Reputation: 67
I'm working on porting a solution from .net 4.5.2 to .net 7.0. In this solution there is a class used to decrypt data which is encoded using MachineKey.Protect on a different device (the data is stored in a database). In .net 7.0 MachineKey.Protect no longer exists.
The original code is as follows:
public class EncryptionHandler
{
public string Protect(byte[] data)
{
if (data == null || data.Length == 0) return null;
var value = MachineKey.Protect(data);
return Convert.ToBase64String(value);
}
public string Unprotect(string value)
{
if (value == "") return value;
return Encoding.Unicode.GetString(MachineKey.Decode(value, MachineKeyProtection.Encryption));
}
internal void HackMachineKey() //This is used to insert the machinekey from the other device
{
var getter = typeof(MachineKeySection).GetMethod("GetApplicationConfig", BindingFlags.Static | BindingFlags.NonPublic);
var config = (MachineKeySection)getter.Invoke(null, null);
Console.WriteLine("Current Decryptionkey: " + config.DecryptionKey);
var readOnlyField = typeof(ConfigurationElement).GetField("_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
readOnlyField.SetValue(config, false);
config.DecryptionKey = Properties.Settings.Default.MachineKeyDecryptionKey;
config.ValidationKey = Properties.Settings.Default.MachineKeyValidationKey;
readOnlyField.SetValue(config, true);
}
}
In my port to .net 7 I try to insert the keys as "purposes", but that obviously is not working:
internal class NewEncryptionHandler
{
private static Logger _logger = LogManager.GetCurrentClassLogger();
private IDataProtector _protector;
//ToDo: move to external config
private string _decryptionKey = "myMachineKey";
private string _validationKey = "myValidationKey";
internal NewEncryptionHandler(Config config)
{
var provider = DataProtectionProvider.Create("EzGetSettings");
_protector = provider.CreateProtector(config.DecryptionKey, config.ValidationKey, "MachineKeyProtection.All");
}
internal string Unprotect(string? value)
{
byte[] protectedData = Encoding.UTF8.GetBytes( value);
var unprotected= _protector.Unprotect(protectedData);
return Convert.ToBase64String(unprotected);
}
}
I'm unsure how to create or config the DataProtectionProvider properly. Any help would be much appreciated!
Upvotes: 0
Views: 128
Reputation: 1850
Following this Example from the documentation.
Make sure to add this in the Program.cs
.
builder.Services.AddDataProtection();
Then in your class Dependency inject the interface IDataProtectionProvider
in the constructor like below:
public class NewEncryptionHandler
{
IDataProtector _protector;
public NewEncryptionHandler(IDataProtectionProvider provider)
{
_protector = provider.CreateProtector("purpose");
}
}
and then in your NewEncryptionHandler
to encrypt:
var encrypted = _protector.Protect("TEST");
to decrypt:
var decrypted = _protector.Unprotect(encrypted);
EDIT
An Example with Console and using the main method:
static void Main(string[] args)
{
// add data protection services
var serviceCollection = new ServiceCollection();
serviceCollection.AddDataProtection();
var serviceProvider = serviceCollection.BuildServiceProvider();
// Create a data protector
var dataProtector = serviceProvider.GetService<IDataProtectionProvider>();
// Create an instance of NewEncryptionHandler
var newEncryptionHandler = new NewEncryptionHandler(dataProtector);
// Call encryption and decryption methods
var plainText = "Hello, world!";
var encryptedData = newEncryptionHandler.EncryptData(plainText);
var decryptedText = newEncryptionHandler.DecryptData(encryptedData);
Console.WriteLine($"Plain text: {plainText}");
Console.WriteLine($"Encrypted data: {encryptedData}");
Console.WriteLine($"Decrypted text: {decryptedText}");
}
The NewEncryptionHandler
Class:
public class NewEncryptionHandler
{
private readonly IDataProtector _dataProtector;
public NewEncryptionHandler(IDataProtectionProvider dataProtector)
{
_dataProtector = dataProtector.CreateProtector("purpose");
}
public string EncryptData(string plainText)
{
// Encrypt data using the data protector
return _dataProtector.Protect(plainText);
}
public string DecryptData(string encryptedData)
{
// Decrypt data using the data protector
return _dataProtector.Unprotect(encryptedData);
}
}
Upvotes: 1