如何在SQL中使用相同的算法加密数据

时间:2013-01-04 08:52:43

标签: .net sql encryption sql-server-2008-r2

  

可能重复:
  Base64 encoding in SQL Server 2005 T-SQL

我有一个.net程序,可以像这样加密数据。

public static string EncryptStringAES(string plainMessage)
{
    string strmsg = string.Empty;
    try
    {
        byte[] encode = new byte[plainMessage.Length];
        encode = Encoding.UTF8.GetBytes(plainMessage);
        strmsg = Convert.ToBase64String(encode);
    }
    catch (Exception ex)
    {
    }
    return strmsg;
}

我喜欢在SQL Server中实现相同的加密。这是否可以在SQL Server中获得相同的加密。

1 个答案:

答案 0 :(得分:1)

您需要采取一些步骤来做您想做的事情。首先,如果你能找到使用你在C#代码中使用的相同加密算法的东西,那么你应该只使用现有的库(确保它是一个安全的实现)。以下答案将为您提供您想去的地方,但请确保将salt值更改为您可以使用的随机盐,和/或查找如何在不使用Rfc2898DeriveBytes类的情况下传入IV和密钥。< / p>

首先,您需要一个可以进行加密的类,这个类既可以用于您拥有.net代码的项目,也可以用于创建在SQL Server上获取它的项目。

internal class AES
{
    static readonly byte[] u8_Salt = new byte[] { 0x26, 0x19, 0x81, 0x4E, 0xA0, 0x6D, 0x95, 0x34, 0x26, 0x75, 0x64, 0x05, 0xF6 };

    public static string EncryptString(string plainText, string password)
    {
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, u8_Salt);
        using (RijndaelManaged i_Alg = new RijndaelManaged { Key = pdb.GetBytes(32), IV = pdb.GetBytes(16) })
        {
            using (var memoryStream = new MemoryStream())
            using (var cryptoStream = new CryptoStream(memoryStream, i_Alg.CreateEncryptor(), CryptoStreamMode.Write))
            {
                byte[] data = Encoding.UTF8.GetBytes(plainText);
                cryptoStream.Write(data, 0, data.Length);
                cryptoStream.FlushFinalBlock();

                return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
            }
        }
    }

    public static string Decrypt(string cipherText, string password)
    {
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, u8_Salt);

        using (RijndaelManaged i_Alg = new RijndaelManaged { Padding = PaddingMode.Zeros, Key = pdb.GetBytes(32), IV = pdb.GetBytes(16) })
        {
            using (var memoryStream = new MemoryStream())
            {
                using (var cryptoStream = new CryptoStream(memoryStream, i_Alg.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    byte[] data = Convert.FromBase64String(cipherText);
                    cryptoStream.Write(data, 0, data.Length);
                    cryptoStream.Flush();

                    return Encoding.UTF8.GetString(memoryStream.ToArray());
                }
            }
        }
    }
}

接下来,您需要为SQL Server创建一个CLR类。这是一个相当简单的过程,只需创建一个新项目并将该类添加到您的项目中。创建项目后,添加一个将包装加密类的新类。

public class AESManagedProc
{
    [Microsoft.SqlServer.Server.SqlFunction]
    public static string Encrypt(string plainText, string password)
    {
        return AES.EncryptString(plainText, password);
    }

    [Microsoft.SqlServer.Server.SqlFunction]
    public static string Decrypt(string cipherText, string password)
    {
        return AES.Decrypt(cipherText, password);
    }
}

您的项目现在应该如下所示 Project file list

下一步是将它放到SQL Server上。您需要首先确保在SQL SErver上启用了clr,因此要启用它,请使用master数据库并执行以下操作:

 sp_configure 'clr enabled', 1;
 GO
 RECONFIGURE;
 GO

接下来创建程序集

 CREATE ASSEMBLY AESEncryption FROM 'C:\PATH_TO_YOUR_DLL\SqlExtensions.dll' WITH PERMISSION_SET = SAFE;

最后创建两个包装函数,一个用于加密,另一个用于解密:

CREATE FUNCTION EncryptString
(
    @plainText nvarchar(max), @password nvarchar(max)
)
RETURNS nvarchar(max)
AS 
    EXTERNAL NAME AESEncryption.[SqlExtensions.AESManagedProc].Encrypt

GO

CREATE FUNCTION DecryptString
(
    @cipherText nvarchar(max), @password nvarchar(max)
)
RETURNS nvarchar(max)
AS 
    EXTERNAL NAME AESEncryption.[SqlExtensions.AESManagedProc].Decrypt
GO

现在要在SQL Server上加密,只需调用加密/解密函数。

SELECT dbo.EncryptString('test','test');
SELECT dbo.DecryptString(dbo.EncryptString('test','test'), 'test');

Desclaimer 请确保您在我给您的代码中不使用u8_salt值,该值在整个互联网上都是示例。其次要确保您的密码存储在安全的地方。选择您的密码 very wisley 它将用于生成您的密钥,因此重要的是它是一个安全的选择。