我希望有人能够帮助我解决我的问题。我的任务是编写一个将由我们的人力资源部门使用的程序。该程序将成为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。我愿意接受任何人的建议。
答案 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")