如何使用VB.NET使用存储在web.config中的密钥加密字段?

时间:2017-07-27 14:39:00

标签: vb.net sql-server-2008 encryption cryptography

我希望有人能够帮助我解决我的问题。我的任务是编写一个将由我们的人力资源部门使用的程序。该程序将成为Intranet的子集,并将根据用户的部门进一步限制。该计划将包含一个员工档案,该档案将存储一些敏感信息,如社会保险号码。我试图找到加密SSN的最佳方法,以便它们不能作为数据库中的纯文本读取。

我找到的代码可以使用System.Security.Cryptography命名空间使用VB.NET的一些内置函数,如here所述。

代码的作用就像数据插入数据库时​​字段被加密一样。我面临的问题是,当我想拉回员工时,我无法解密。我的猜测是因为我在需要解密值的页面上执行此操作:

Dim rsa As New RSACryptoServiceProvider

这基本上定义了一个新的加密服务提供程序,而不是我用来加密数据的第一个加密服务提供程序。我想知道当你做新的RSACryptoServiceProvider时,它是否会出现一个新的公钥/私钥对?

我的下一个想法是看看如何在web.config中存储加密和解密密钥,以便无论用户在哪个页面上都可以解密数据。我没有找到一个使用它的好例子,因为我看到的一切都显示了如何加密/解密web.config中的字段(例如密码和数据库的连接),而不是在应用程序中实际使用它。这是加密数据的好方法吗?如上所述,这将是内联网的一个子集,因此应用程序将在本地保存,不会暴露在外部。我对SSN在数据库中的可读性感到非常不舒服。

这是我第一次涉及加密,所以如果这是一个简单的问题我会道歉。

我在Visual Studio 2015中使用VB.NET连接到SQL SERVER 2008 R2。我愿意接受任何人的建议。

2 个答案:

答案 0 :(得分:0)

您必须记住,加密数据仅受加密密钥保护。将加密密钥存储在web.config或任何其他文件中,虽然方便,但并不十分安全。

使用仅限数据库工具执行所需操作的一种方法是:

要使用数据库密钥加密SSN列,您可以控制谁有权访问密钥,从而控制谁可以解密数据。 您可以选择创建一个将尝试解密数据的View,或者如果用户无权访问解密密钥,则返回NULL。

我建议使用KEY_SOURCE字符串创建密钥,以便您可以在发生灾难时重新创建密钥,还可以备份数据库主密钥,无法执行此操作以及不执行恢复测试留下难以置信的数据丢失。

进一步的细节在这篇伟大的文章中: https://www.mssqltips.com/sqlservertip/3081/using-views-to-expose-encrypted-data-in-sql-server/

答案 1 :(得分:0)

我已经想出了如何做我想要的事情。虽然Alex的解决方案有效,但在VB.NET代码中完成加密可以传递不同的密钥,以便不同地加密不同的数据部分。基本上如果有人碰巧得到其中一个键,他们只会有一些数据,而不是所有数据。这不是一个完美的解决方案,但它比在数据库中将字段显示为纯文本更好。

我创建了一个类文件并将其放在App_Code文件夹中并将其命名为Simple3Des。该课程如下:

Imports System.Security.Cryptography

Public Class Simple3Des

    Private TripleDes As New TripleDESCryptoServiceProvider

    Private Shared Function TruncateHash(ByVal key As String, ByVal length As Integer) As Byte()
        Dim sha1 As New SHA1CryptoServiceProvider
        //hash the key
        Dim keyBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(key)
        Dim hash() As Byte = sha1.ComputeHash(keyBytes)
        //truncate or pad the hash
        ReDim Preserve hash(length - 1)
        Return hash
    End Function

    Public Shared Function EncryptData(ByVal plaintext As String, ByVal key As String) As String
        //convert the plaintext string to a byte array
        Dim threeDes As New TripleDESCryptoServiceProvider
        threeDes.Key = TruncateHash(key, threeDes.KeySize \ 8)
        threeDes.IV = TruncateHash("", threeDes.BlockSize \ 8)
        Dim plaintextBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(plaintext)
        //create the stream
        Dim ms As New System.IO.MemoryStream
        //create the encoder to write the byte array to the stream
        Dim encStream As New CryptoStream(ms, threeDes.CreateEncryptor(), System.Security.Cryptography.CryptoStreamMode.Write)
        encStream.Write(plaintextBytes, 0, plaintextBytes.Length)
        encStream.FlushFinalBlock()
        //convert the encrypted stream to a printable string
        Return Convert.ToBase64String(ms.ToArray)
    End Function

    Public Shared Function DecryptData(ByVal encryptedtext As String, ByVal key As String) As String
        //convert the encrypted text string to a byte array
        Dim threeDes As New TripleDESCryptoServiceProvider
        threeDes.Key = TruncateHash(key, threeDes.KeySize \ 8)
        threeDes.IV = TruncateHash("", threeDes.BlockSize \ 8)
        Dim encryptedBytes() As Byte = Convert.FromBase64String(encryptedtext)
        //create the stream
        Dim ms As New System.IO.MemoryStream
        //create the decoder to write to the stream
        Dim decStream As New CryptoStream(ms, threedes.CreateDecryptor(), System.Security.Cryptography.CryptoStreamMode.Write)
        //use the crypt stream to write the byte array to the stream
        decStream.Write(encryptedBytes, 0, encryptedBytes.Length)
        decStream.FlushFinalBlock()
        //convert the plaintext stream to a string
        Return System.Text.Encoding.Unicode.GetString(ms.ToArray)
    End Function

End Class

然后使用以下内容来调用该类:

//to encrypt
Simple3Des.EncryptData("Data to encrypt", "key")
//to decrypt
Simple3Des.DecryptData("Data to decrypt", "key")