-1

可能重复:
SQL Server 2005 T-SQL 中的 Base64 编码

我有一个 .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 中获得相同的加密。

4

1 回答 1

1

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

首先,您需要一个将进行加密的类,该类既可用于您拥有 .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);
    }
}

你的项目现在应该是这样的 项目文件清单

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

 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');

免责声明确保您没有在我给您的代码中使用 u8_salt 值,该值在互联网上的示例中随处可见。其次,确保您的密码存储在安全的地方。非常明智地选择您的密码,它将用于生成您的密钥,因此重要的是它是一个安全的选择。

于 2013-01-04T20:07:45.343 回答