C# 使用NHibernate加密和解密数据
我正在编写一个可公开访问的web应用程序,其中将包含个人用户数据,如姓名和出生日期,我需要以一种对可能访问原始数据的人很难解密的形式对这些数据进行加密。我正在使用、mySQL和C#3.5C# 使用NHibernate加密和解密数据,c#,mysql,nhibernate,C#,Mysql,Nhibernate,我正在编写一个可公开访问的web应用程序,其中将包含个人用户数据,如姓名和出生日期,我需要以一种对可能访问原始数据的人很难解密的形式对这些数据进行加密。我正在使用、mySQL和C#3.5 我应该使用什么方法对用户信息进行行业标准的加密和解密?加密方法不应依赖于数据库 如何告诉nHibernate使用一个简单的属性对某些映射类进行透明加密/解密,如StorageType=StorageType.Encrypted。我不介意生成的数据库表是否只有一列或两列,或者每个加密字段只有一列。根据我的发现,我
StorageType=StorageType.Encrypted
。我不介意生成的数据库表是否只有一列或两列,或者每个加密字段只有一列。根据我的发现,我应该从IUserDataType
创建自己的数据类型,并在构造函数中加密数据。这是正确的吗在真正的蓝色彼得时装,这里有一个我创造了早些时候做这件事。它依赖于提供程序模式来获取加密算法,但是您可以用任何您想要的方式来替换它 这将在域对象中公开字符串属性,但将其作为表示加密形式的二进制(字节数组)持久化。在我的提供者模式代码中,Encrypt接受一个字符串并返回一个字节数组,Decrypt则相反
[Serializable]
public class EncryptedStringType : PrimitiveType
{
public EncryptedStringType() : this(new BinarySqlType()) {}
public EncryptedStringType(SqlType sqlType) : base(sqlType) {}
public override string Name
{
get { return "String"; }
}
public override Type ReturnedClass
{
get { return typeof (string); }
}
public override Type PrimitiveClass
{
get { return typeof (string); }
}
public override object DefaultValue
{
get { return null; }
}
public override void Set(IDbCommand cmd, object value, int index)
{
if (cmd == null) throw new ArgumentNullException("cmd");
if (value == null)
{
((IDataParameter)cmd.Parameters[index]).Value = null;
}
else
{
((IDataParameter)cmd.Parameters[index]).Value = EncryptionManager.Provider.Encrypt((string)value);
}
}
public override object Get(IDataReader rs, int index)
{
if (rs == null) throw new ArgumentNullException("rs");
var encrypted = rs[index] as byte[];
if (encrypted == null) return null;
return EncryptionManager.Provider.Decrypt(encrypted);
}
public override object Get(IDataReader rs, string name)
{
return Get(rs, rs.GetOrdinal(name));
}
public override object FromStringValue(string xml)
{
if (xml == null)
{
return null;
}
if (xml.Length % 2 != 0)
{
throw new ArgumentException(
"The string is not a valid xml representation of a binary content.",
"xml");
}
var bytes = new byte[xml.Length / 2];
for (int i = 0; i < bytes.Length; i++)
{
string hexStr = xml.Substring(i * 2, (i + 1) * 2);
bytes[i] = (byte)(byte.MinValue
+ byte.Parse(hexStr, NumberStyles.HexNumber, CultureInfo.InvariantCulture));
}
return EncryptionManager.Provider.Decrypt(bytes);
}
public override string ObjectToSQLString(object value, Dialect dialect)
{
var bytes = value as byte[];
if (bytes == null)
{
return "NULL";
}
var builder = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
string hexStr = (bytes[i] - byte.MinValue).ToString("x", CultureInfo.InvariantCulture);
if (hexStr.Length == 1)
{
builder.Append('0');
}
builder.Append(hexStr);
}
return builder.ToString();
}
}
[可序列化]
公共类EncryptedStringType:PrimitiveType
{
public EncryptedStringType():此(新的二进制SqlType()){}
公共EncryptedStringType(SqlType SqlType):基(SqlType){}
公共重写字符串名
{
获取{返回“字符串”;}
}
公共重写类型ReturnedClass
{
获取{return typeof(string);}
}
公共重写类型基元类
{
获取{return typeof(string);}
}
公共覆盖对象默认值
{
获取{return null;}
}
公共覆盖无效集(IDbCommand cmd,对象值,int索引)
{
如果(cmd==null)抛出新的ArgumentNullException(“cmd”);
如果(值==null)
{
((IDataParameter)cmd.Parameters[index]).Value=null;
}
其他的
{
((IDataParameter)cmd.Parameters[index]).Value=EncryptionManager.Provider.Encrypt((字符串)值);
}
}
公共重写对象Get(IDataReader rs,int索引)
{
如果(rs==null)抛出新的ArgumentNullException(“rs”);
var encrypted=rs[index]作为字节[];
if(encrypted==null)返回null;
返回EncryptionManager.Provider.Decrypt(加密);
}
公共重写对象Get(IDataReader rs,字符串名称)
{
返回Get(rs,rs.GetOrdinal(name));
}
公共重写对象FromStringValue(字符串xml)
{
if(xml==null)
{
返回null;
}
如果(xml.Length%2!=0)
{
抛出新的ArgumentException(
“该字符串不是二进制内容的有效xml表示形式。”,
“xml”);
}
var bytes=新字节[xml.Length/2];
for(int i=0;i
我将创建一个EncryptionService,使用您想要的任何密钥对字符串进行加密。然后我将在你的实体中创建两个属性。一个是NHibernate与之交互的(加密值),另一个是您(或其他开发人员)与之交互的,将自动加密值
见:
下面是EncryptionService、用户实体和用户映射的示例
public class User
{
private readonly EncryptionService _encryptionService =
new EncryptionService();
public virtual int Id { get; set; }
public virtual DateTime? DateOfBirth
{
get
{
return _encryptionService.DecryptObject<DateTime?>(DateOfBirthEncrypted);
}
set
{
DateOfBirthEncrypted= _encryptionService.EncryptString(value.Value
.ToString("yyyy-MM-dd HH:mm:ss"));
}
}
[Obsolete("Use the 'DateOfBirth' property -- this property is only to be used by NHibernate")]
public virtual string DateOfBirthEncrypted { get; set; }
}
public sealed class UserMap : ClassMap<User>
{
public UserMap()
{
WithTable("dbo.[User]");
Id(x => x.Id, "[ID]");
Map(x => x.DateOfBirthEncrypted, "DOB");
}
}
公共类用户
{
私有只读加密服务\u加密服务=
新的EncryptionService();
公共虚拟整数Id{get;set;}
公共虚拟日期时间?出生日期
{
得到
{
返回_encryptionService.DecryptObject(BurthenCrypted的日期);
}
设置
{
DateOfBurthenCrypted=\u encryptionService.EncryptString(value.value
.ToString(“yyyy-MM-dd HH:MM:ss”);
}
}
[过时(“使用“DateOfBirth”属性——此属性仅由NHibernate使用”)]
公共虚拟字符串DateOfBirthEncrypted{get;set;}
}
公共密封类UserMap:ClassMap
{
公共用户映射()
{
WithTable(“dbo.[User]”;
Id(x=>x.Id,“[Id]”);
映射(x=>x.DateOfBirthEncrypted,“DOB”);
}
}
以及EncryptionService:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Services
{
public class EncryptionService : IEncryptionService
{
/// <summary>
/// Decrypts a string
/// </summary>
/// <param name="encryptedString"></param>
/// <returns></returns>
public String DecryptString(string encryptedString)
{
if (String.IsNullOrEmpty(encryptedString)) return String.Empty;
try
{
using (TripleDESCryptoServiceProvider cypher = new TripleDESCryptoServiceProvider())
{
PasswordDeriveBytes pdb = new PasswordDeriveBytes("ENTERAKEYHERE", new byte[0]);
cypher.Key = pdb.GetBytes(16);
cypher.IV = pdb.GetBytes(8);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, cypher.CreateDecryptor(), CryptoStreamMode.Write))
{
byte[] data = Convert.FromBase64String(encryptedString);
cs.Write(data, 0, data.Length);
cs.Close();
return Encoding.Unicode.GetString(ms.ToArray());
}
}
}
}
catch
{
return String.Empty;
}
}
/// <summary>
/// Encrypts a string
/// </summary>
/// <param name="decryptedString"
/// <returns></returns>
public String EncryptString(string decryptedString)
{
if (String.IsNullOrEmpty(decryptedString)) return String.Empty;
using (TripleDESCryptoServiceProvider cypher = new TripleDESCryptoServiceProvider())
{
PasswordDeriveBytes pdb = new PasswordDeriveBytes("ENTERAKEYHERE", new byte[0]);
cypher.Key = pdb.GetBytes(16);
cypher.IV = pdb.GetBytes(8);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, cypher.CreateEncryptor(), CryptoStreamMode.Write))
{
byte[] data = Encoding.Unicode.GetBytes(decryptedString);
cs.Write(data, 0, data.Length);
cs.Close();
return Convert.ToBase64String(ms.ToArray());
}
}
}
}
/// <summary>
/// Decrypts a given value as type of T, if unsuccessful the defaultValue is used
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public T DecryptObject<T>(object value, T defaultValue)
{
if (value == null) return defaultValue;
try
{
Type conversionType = typeof(T);
// Some trickery for Nullable Types
if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
conversionType = new NullableConverter(conversionType).UnderlyingType;
}
return (T)Convert.ChangeType(DecryptString(Convert.ToString(value)), conversionType);
}
catch
{
// Do nothing
}
return defaultValue;
}
}
}
使用系统;
使用System.IO;
使用System.Security.Cryptography;
使用系统文本;
命名空间服务
{
公共类EncryptionService:EncryptionService
{
///
///解密字符串
///
///
///
公共字符串解密字符串(字符串加密字符串)
{
if(String.IsNullOrEmpty(encryptedString))返回String.Empty;
尝试
{
使用(TripleDESCryptoServiceProvider cypher=new TripleDESCryptoServiceProvider())
{
PasswordDeriveBytes pdb=新的PasswordDeriveBytes(“ENTERAKEYHERE”,新字节[0]);
cypher.Key=pdb.GetBytes(16);