sql-server - 基于 key 和初始向量在 SQL Server 中创建对称 AES128 key

标签 sql-server sql-server-2008 aes entity-framework-migrations encryption

我有一些 key 和初始向量,我在我的 .NET 应用程序中使用它们进行加密。假设他们是:

Key = 0x0102030405060708090A0B0C0D0E
IV  = 0xA1A2A3A4A5A6A7A8A9AAABACADAE

在某些情况下,我想在 SQL Server 上(不在应用程序中)执行加密,但在应用程序中解密数据。我认为我可以在数据库中创建一个临时对称 key 并执行加密:
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;

但我不知道我应该提供什么作为 IDENTITY_VALUE 和 KEY_SOURCE 才能在 DB 和我的应用程序之间拥有“共享” key 。

更新 2014-07-07

我想提供一些我的问题的背景。
  • 首先,我使用 EF Code First 方法,当我需要执行一些数据库更新时,我使用 Code First Migrations我想进一步使用这种基于纯迁移的方法。不幸的是,正如在问题 Use custom logic in EF Code First migration 中发现的那样, 无法在 Up 内获取当前的 SqlConnection 和 SqlTransaction或 Down方法。我唯一的方法 - 使用 Sql 执行自定义 SQL 查询方法。
  • 在下一次数据库更新中,我想加密一列中的数据。加密应满足两个条件:(1) 数据应可在客户端应用程序中解密(而不是在 SQL Server 端),(2) 对称 key 应以加密形式存储在客户端应用程序中,并且描述应为使用来自 key 容器的非对称 key 完成。不幸的是,这使得 CRL UDF 在这里无用 - 当我尝试在 UDF 中获取基于 key 容器的 key 时,我得到一个权限异常:System.Security.SecurityException: Request for the permission of type System.Security.Permissions.KeyContainerPermission
  • 在我在 1. 和 2. 期间进行的所有尝试之后,我最终明白我可以尝试使用 CREATE SYMMETRIC KEY 在数据库中创建临时对称 key 查询,但我所有的尝试都没有成功。

  • 希望所有这些都有助于理解问题并找到正确的解决方案。

    最佳答案

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

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

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

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

    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;
    

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

    网络
    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
    

    关于sql-server - 基于 key 和初始向量在 SQL Server 中创建对称 AES128 key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24527430/

    相关文章:

    security - 使用 PKBDF2、AES、IV 和 salt 进行更好的实践

    带有自连接问题的 sqlquery

    sql - 检查 SQL Server 中的组中是否存在确切 ID 的逻辑

    sql - 计算 SQL 中选定 ID 的列总和

    sql - 如何从特定的大约中获取顶行。使用 sql server 2008 的百分比?

    java - 加密数据随机存取 AES GCM模式

    go - Go 是否只加密 16 字节消息长度的文本?

    sql - 自动测试存储过程是否仍然有效 + SQL SERVER

    sql-server-2008 - 如何解决 Microsoft SQL 对 AppHarbor 地理类型的依赖

    sql-server-2008 - 将 sql xml 数据类型转换为表