我正在将一个网站移植到dnx /aspnet5 5/mvc6 6。我需要将密码存储到数据库中的第三方站点(本质上是一个聚合器)。
在早期的mvc版本中,我使用像RijndaelManaged这样的类来完成这个任务。但这些似乎并不存在于dnx核心。事实上,我还没有在dnx内核中找到很多关于任何通用加密/解密内容的文档。
在mvc6站点中加密/解密单个字段值的推荐方法是什么?我不想加密整个sql server数据库。
或者我应该考虑一种不同的方法来存储访问受密码保护的第三方站点所需的凭据?
发布于 2016-01-29 18:58:32
他们的关于将其用于持久数据保护的指南有点模糊,但他们说没有技术原因你不能这么做。基本上,要持久地存储受保护的数据,您需要允许使用过期的密钥解除对其的保护,因为密钥在您保护它之后可能过期。
在我看来,使用它似乎是合理的,而且我正在我自己的计划中使用它。
由于IPersistedDataProtector只提供带有字节数组的方法,所以我创建了几个扩展方法来从字符串来回转换字节。
public static class DataProtectionExtensions
{
public static string PersistentUnprotect(
this IPersistedDataProtector dp,
string protectedData,
out bool requiresMigration,
out bool wasRevoked)
{
bool ignoreRevocation = true;
byte[] protectedBytes = Convert.FromBase64String(protectedData);
byte[] unprotectedBytes = dp.DangerousUnprotect(protectedBytes, ignoreRevocation, out requiresMigration, out wasRevoked);
return Encoding.UTF8.GetString(unprotectedBytes);
}
public static string PersistentProtect(
this IPersistedDataProtector dp,
string clearText)
{
byte[] clearBytes = Encoding.UTF8.GetBytes(clearText);
byte[] protectedBytes = dp.Protect(clearBytes);
string result = Convert.ToBase64String(protectedBytes);
return result;
}
}我还创建了一个helper类,专门用于在SiteSettings对象被持久化到db之前保护它上的某些属性。
using cloudscribe.Core.Models;
using Microsoft.AspNet.DataProtection;
using Microsoft.Extensions.Logging;
using System;
namespace cloudscribe.Core.Web.Components
{
public class SiteDataProtector
{
public SiteDataProtector(
IDataProtectionProvider dataProtectionProvider,
ILogger<SiteDataProtector> logger)
{
rawProtector = dataProtectionProvider.CreateProtector("cloudscribe.Core.Models.SiteSettings");
log = logger;
}
private ILogger log;
private IDataProtector rawProtector = null;
private IPersistedDataProtector dataProtector
{
get { return rawProtector as IPersistedDataProtector; }
}
public void Protect(ISiteSettings site)
{
if (site == null) { throw new ArgumentNullException("you must pass in an implementation of ISiteSettings"); }
if (site.IsDataProtected) { return; }
if (dataProtector == null) { return; }
if (site.FacebookAppSecret.Length > 0)
{
try
{
site.FacebookAppSecret = dataProtector.PersistentProtect(site.FacebookAppSecret);
}
catch (System.Security.Cryptography.CryptographicException ex)
{
log.LogError("data protection error", ex);
}
}
// ....
site.IsDataProtected = true;
}
public void UnProtect(ISiteSettings site)
{
bool requiresMigration = false;
bool wasRevoked = false;
if (site == null) { throw new ArgumentNullException("you must pass in an implementation of ISiteSettings"); }
if (!site.IsDataProtected) { return; }
if (site.FacebookAppSecret.Length > 0)
{
try
{
site.FacebookAppSecret = dataProtector.PersistentUnprotect(site.FacebookAppSecret, out requiresMigration, out wasRevoked);
}
catch (System.Security.Cryptography.CryptographicException ex)
{
log.LogError("data protection error", ex);
}
catch (FormatException ex)
{
log.LogError("data protection error", ex);
}
}
site.IsDataProtected = false;
if (requiresMigration || wasRevoked)
{
log.LogWarning("DataProtection key wasRevoked or requires migration, save site settings for " + site.SiteName + " to protect with a new key");
}
}
}
}如果应用程序需要在数据受到保护后迁移到其他机器,那么您还想控制密钥位置,默认情况下会将键放在机器的OS键环上,据我所知,这非常像机器键,在过去,您会在web.config中重写它,使其具有可移植性。当然,在这一点上,保护钥匙是你的责任。在我的项目启动时,我有这样的代码
//If you change the key persistence location, the system will no longer automatically encrypt keys
// at rest since it doesn’t know whether DPAPI is an appropriate encryption mechanism.
services.ConfigureDataProtection(configure =>
{
string pathToCryptoKeys = appBasePath + Path.DirectorySeparatorChar
+ "dp_keys" + Path.DirectorySeparatorChar;
// these keys are not encrypted at rest
// since we have specified a non default location
// that also makes the key portable so they will still work if we migrate to
// a new machine (will they work on different OS? I think so)
// this is a similar server migration issue as the old machinekey
// where we specified a machinekey in web.config so it would not change if we
// migrate to a new server
configure.PersistKeysToFileSystem(new DirectoryInfo(pathToCryptoKeys));
});因此,在本例中,我的密钥存储在appRoot/dp_key中。
发布于 2016-02-01 22:53:47
如果你想手工做事;
添加对System.Security.Cryptography.Algorithms的引用
然后,您可以通过create方法创建每个算法类型的实例。例如;
var aes = System.Security.Cryptography.Aes.Create();https://stackoverflow.com/questions/35091051
复制相似问题