c# - 使用 NHibernate 加密和解密数据

标签 c# mysql nhibernate

我正在编写一个可公开访问的 Web 应用程序,其中将包含个人用户数据,例如姓名和出生日期,并且我需要以一种对于可能访问原始数据的人来说很难的形式加密这些数据要解密的数据。我正在使用 Fluent NHibernate 、mySQL 和 C# 3.5。

  1. 我应该使用什么方法对用户信息进行行业标准加密和解密?加密方法不应依赖于数据库。

  2. 我如何告诉 nHibernate 对具有简单属性的某些映射类进行透明加密/解密,例如 StorageType = StorageType.Encrypted。我不介意生成的数据库表是否只有一列或两列,或者每个加密字段一列。根据我的发现,我应该从 IUserDataType 创建我自己的数据类型并在构造函数中加密数据。这是正确的吗?

最佳答案

在真正的 Blue Peter 时尚中,这是我之前创建的一个。它依赖于提供者模式来获取加密算法,但您可以将其替换为您想要的任何内容。

这会在您的域对象中公开一个字符串属性,但将其作为表示加密形式的二进制(字节数组)持久保存。在我的提供者模式代码中,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();
    }
}

关于c# - 使用 NHibernate 加密和解密数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/847884/

相关文章:

c# - 使用 DLLImport 导入一个类

c# - 简单线程问题

nhibernate - 如何更改 Linq-to-Nhibernate 为特定列生成的 SQL?

nhibernate - 使用 NHibernate 将属性映射到另一个表

c# - System.IO.FileNotFoundException : myCSharpDemoCalc\work\MyCSharpDemoCalc. j4n.dll

c# - IdentityDbContext.SaveChanges 在 Claims.Remove 或 Claims.Clear 之后失败

用于存储未读帖子和通知的 PHP 想法

MySQL 列间搜索

mysql - 搜索 3 个值的组合

c# - SQL SERVER 删除大量行优化