基于Key和Initial Vector在SQL Server中创建对称AES128密钥

ie.*_*ie. 5 sql-server encryption aes sql-server-2008 ef-migrations

我有一些Key和Initial Vector,我在.NET应用程序中用于加密.让我们说它们是:

Key = 0x0102030405060708090A0B0C0D0E
IV  = 0xA1A2A3A4A5A6A7A8A9AAABACADAE
Run Code Online (Sandbox Code Playgroud)

在某些情况下,我想在SQL Server上执行加密(不在应用程序中),但在应用程序中解密数据.我以为我可以在数据库中创建临时对称密钥并执行加密:

CREATE SYMMETRIC KEY #TempKey
    WITH ALGORITHM   = AES_128
    , IDENTITY_VALUE = ???
    , KEY_SOURCE     = ???
    ENCRYPTION BY PASSWORD = 'Pa$$w0rd';

OPEN SYMMETRIC KEY #TempKey
    DECRYPTION BY PASSWORD = 'Pa$$w0rd';

SELECT EncryptByKey(Key_Guid('#TempKey'), 'Secret Data');

CLOSE SYMMETRIC KEY #TempKey;
DROP SYMMETRIC KEY #TempKey;
Run Code Online (Sandbox Code Playgroud)

但我不知道我应该提供什么作为IDENTITY_VALUE和KEY_SOURCE在DB和我的应用程序之间有一个"共享"键.



更新2014-07-07

我想提供一些问题的背景知识.

  1. 首先,我正在使用EF Code First方法,当我需要执行一些数据库更新时,我使用Code First Migrations,我想进一步使用这种基于纯迁移的方法.不幸的是,正如在EF Code First迁移中使用自定义逻辑的问题中找到的那样,无法在UpDown方法中获取当前的SqlConnection和SqlTransaction .我唯一的方法 - 使用Sql方法执行自定义SQL查询.

  2. 在下一个数据库更新中,我想要在一列中加密数据.加密应该满足两个条件:(1)数据应该在客户端应用程序中解密(不在SQL Server端),(2)对称密钥应该以加密形式存储在客户端应用程序中,描述应该是使用密钥容器中的非对称密钥完成.不幸的是,这使得CRL UDF在这里无用 - 当我尝试在UDF中获取基于密钥容器的密钥时,我得到一个权限异常:System.Security.SecurityException: Request for the permission of type System.Security.Permissions.KeyContainerPermission

  3. 经过我在1和2期间所做的所有尝试后,我最终了解到我可以尝试使用CREATE SYMMETRIC KEY查询在数据库中创建临时对称密钥,但我所做的所有尝试都没有成功.

希望这一切都有助于理解问题并找到正确的解决方案.

小智 0

首先,我建议您阅读这篇文章,这是一篇关于对称加密的含义以及如何使用它的非常好的文章。 http://benjii.me/2010/05/how-to-use-sql-server-encryption-with-symmetry-keys/

关于如何解密.Net中的数据,请阅读此处: http://msdn.microsoft.com/en-us/library/te15te69%28v=vs.110%29.aspx ?cs-save-lang=1&cs-lang= csharp#code-snippet-1

然后,简而言之,是这样的:在服务器上创建一个对称密钥,指定硬编码的identity_value和key_source。在应用程序端,使用相同的identity_value (IV) 和key_source (KEY) 值创建对称密钥。

下面是一个关于如何在 sql server 和 vb.net 中加密/解密值的示例。希望能帮助到你。vb.net 示例基于此处的另一个线程

=================================================== ===================

SQL服务器:

declare @value varchar(max) = 'I am a very secret value', @encripted_value varchar(max)

--encription on server side
CREATE SYMMETRIC KEY #TempKey
    WITH ALGORITHM   = AES_128
    , IDENTITY_VALUE = 'abcdefgh'
    , KEY_SOURCE     = 'zxcvzxcv'
    ENCRYPTION BY PASSWORD = 'Pa$$w0rd1234';

OPEN SYMMETRIC KEY #TempKey
    DECRYPTION BY PASSWORD = 'Pa$$w0rd1234';

SELECT @encripted_value = cast( EncryptByKey(Key_Guid('#TempKey') , @value) as varchar(max));

select @encripted_value

CLOSE SYMMETRIC KEY #TempKey;
DROP SYMMETRIC KEY #TempKey;


--decription in server side, I put it here only for example
CREATE SYMMETRIC KEY #TempKey1
    WITH ALGORITHM   = AES_128
    , IDENTITY_VALUE = 'abcdefgh'
    , KEY_SOURCE     = 'zxcvzxcv'
    ENCRYPTION BY PASSWORD = 'Pa$$w0rd1234';

OPEN SYMMETRIC KEY #TempKey1
    DECRYPTION BY PASSWORD = 'Pa$$w0rd1234';

SELECT cast(DecryptByKey(@encripted_value) as varchar(max)) ;

CLOSE SYMMETRIC KEY #TempKey1;
DROP SYMMETRIC KEY #TempKey1;
Run Code Online (Sandbox Code Playgroud)

=================================================== ===========================

网络

Imports System
Imports System.IO
Imports System.Xml
Imports System.Text
Imports System.Security.Cryptography

Module Module1

Private key() As Byte = {}
Private IV() As Byte = {}

Private Const EncryptionKey As String = "abcdefgh"
Private Const IdentityValue As String = "zxcvzxcv"


Public Function Decrypt(ByVal stringToDecrypt As String) As String
    Try
        Dim inputByteArray(stringToDecrypt.Length) As Byte
        key = System.Text.Encoding.UTF8.GetBytes(EncryptionKey)
        IV = System.Text.Encoding.UTF8.GetBytes(IdentityValue)
        Dim des As New DESCryptoServiceProvider
        inputByteArray = Convert.FromBase64String(stringToDecrypt)
        Dim ms As New MemoryStream
        Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV), CryptoStreamMode.Write)
        cs.Write(inputByteArray, 0, inputByteArray.Length)
        cs.FlushFinalBlock()
        Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
        Return Convert.ToBase64String(ms.ToArray())
    Catch ex As Exception
        Return vbNull
    End Try
End Function


Public Function Encrypt(ByVal stringToEncrypt As String) As String
    Try
        key = System.Text.Encoding.UTF8.GetBytes(EncryptionKey)
        IV = System.Text.Encoding.UTF8.GetBytes(IdentityValue)
        Dim des As New DESCryptoServiceProvider
        Dim inputByteArray() As Byte = Encoding.UTF8.GetBytes(stringToEncrypt)
        Dim ms As New MemoryStream
        Dim cs As New CryptoStream(ms, des.CreateEncryptor(key, IV), CryptoStreamMode.Write)
        cs.Write(inputByteArray, 0, inputByteArray.Length)
        cs.FlushFinalBlock()
        Return Convert.ToBase64String(ms.ToArray())
    Catch ex As Exception
        Return vbNull
    End Try
End Function

End Module
Run Code Online (Sandbox Code Playgroud)