提问人:David 提问时间:11/14/2023 更新时间:11/15/2023 访问量:48
将 machinekey.protect 加密从 .net 4.5 移植到 .net 7.0 (c#)
Porting machinekey.protect encryption from .net 4.5 to .net 7.0 (c#)
问:
我正在努力将解决方案从 .net 4.5.2 移植到 .net 7.0。在此解决方案中,有一个用于解密数据的类,该类在不同的设备上使用 MachineKey.Protect 进行编码(数据存储在数据库中)。在 .net 7.0 中,MachineKey.Protect 不再存在。
原代码如下:
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);
}
}
在我移植到 .net 7 的端口中,我尝试插入键作为“目的”,但这显然不起作用:
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);
}
}
我不确定如何正确创建或配置 DataProtectionProvider。任何帮助将不胜感激!
答:
1赞
Denis Micheal
11/14/2023
#1
按照文档中的此示例进行操作。
确保将其添加到 .Program.cs
builder.Services.AddDataProtection();
然后在你的类 Dependency 中,在构造函数中注入接口,如下所示:IDataProtectionProvider
public class NewEncryptionHandler
{
IDataProtector _protector;
public NewEncryptionHandler(IDataProtectionProvider provider)
{
_protector = provider.CreateProtector("purpose");
}
}
然后在你的加密中:NewEncryptionHandler
var encrypted = _protector.Protect("TEST");
要解密:
var decrypted = _protector.Unprotect(encrypted);
编辑
使用 Console 并使用 main 方法的示例:
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}");
}
班级:NewEncryptionHandler
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);
}
}
评论
0赞
David
11/14/2023
对不起,我没有提到它,但它是一个控制台应用程序,而不是 .net 核心应用程序。所以没有建设者。我不确定如何以这种方式插入服务,或者这是否有必要。主要问题似乎是我错误地设置了 protectionprovider。我的错误消息是:“无法验证数据:System.Security.Cryptography.CryptographicException:无法解密提供的有效负载,因为它未受此保护提供程序的保护。
0赞
Denis Micheal
11/15/2023
还添加了有关如何在控制台上执行此操作的编辑,您也没有分享您是如何调用的,但我假设加密/解密的调用方法是不同的。Protect
_protector
0赞
David
11/15/2023
感谢您的努力,但我不认为这解决了我的问题:数据在另一台机器上使用 .net 4.5 MachineKey.Protect(data) 加密;加密,这就是我只使用 Decrypt 的原因。我遇到的问题是我不知道如何在 IDataProtector 中插入 machinekey。我认为这应该使用 IXmlRepository 来完成,但我不知道如何完成。
0赞
Denis Micheal
11/15/2023
值得一读
评论