0

嘿那里,所以在我使用存储过程保存和检索的 msSQL 数据库中。我试图在放置之前加密 c# windows 表单中的一些数据,然后当我将其拉回时当然会对其进行解密。所有加密都在 c# 端处理。我正在使用来自微软的 TripleDESCryptoService 类(内存版本,第二个示例)逐字加密和解密的示例代码。这些值被加密并发送到数据库,但是在检索它时我得到一个“坏数据”错误。加密调用的示例是...

TripleDESCryptoServiceProvider tDESalg = new TripleDESCryptoServiceProvider();
byte[] tempByte = new byte[100];
tempByte = encrypt(txt_Last_Name.Text, tDESalg.Key, tDESalg.IV);
txt_Last_Name.Text = System.Text.ASCIIEncoding.ASCII.GetString(tempByte);

然后将 txt_Last_Name 发送到数据库,我可以看到数据库中有一些东西。在数据库中,姓氏的类型为 varchar(20)

解密调用的示例是...

TripleDESCryptoServiceProvider tDESalg = new TripleDESCryptoServiceProvider();
string lastName = dr.GetString(dr.GetOrdinal("Last Name"));
if (isEncrypted)
{
     byte[] toDecrypt = new ASCIIEncoding().GetBytes(lastName);
     lastName = decrypt(toDecrypt, tDESalg.Key, tDESalg.IV);                    
}
txt_Last_Name.Text = lastName;

它在解密函数中炸毁:“csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);” 我不明白为什么。我不确定它是否没有正确存储在数据库中,或者我的转换不正确。

如果它意味着什么,进入解密函数的“数据”大小为 16 并且包含非零值,但“byte[] fromEncrypt”是一个大小为 16 的数组,包含全零。

谢谢你的帮助!

4

3 回答 3

3

编辑:好的,我们已经深入了解了……尽管 ASCII 问题也会受到影响。

每次您创建一个新的TripleDESCryptoServiceProvider并要求它提供密钥/IV 时,它都会生成一个新的。您需要将其安全地存储在某处,因为它需要解密数据。否则你没有任何“秘密”所以它不是真正的加密......


这是一个可怕的想法:

txt_Last_Name.Text = System.Text.ASCIIEncoding.ASCII.GetString(tempByte);

您在tempByte. 不要假设它是有效的 ASCII 文本。这几乎肯定是您丢失数据的地方。

使用Convert.ToBase64StringConvert.FromBase64String将不透明的二进制数据安全地编码为文本。

此外,这是一个坏主意:

byte[] tempByte = new byte[100];
tempByte = encrypt(txt_Last_Name.Text, tDESalg.Key, tDESalg.IV);

如果您要忽略它,那么创建字节数组有什么意义?利用

byte[] tempByte = encrypt(txt_Last_Name.Text, tDESalg.Key, tDESalg.IV);

反而。哦,尝试遵循 .NET 命名约定 :)

说了这么多,如果你的加密总是返回一个 16 个零的字节数组,那是你的encrypt方法被破坏的一个非常确定的信号。在您发布该方法的代码之前,我们无法真正提供帮助。

最后,如果您的列是类型varchar(20),您应该知道,这很可能无法保存您需要的所有数据......特别是如果您要包含盐。Base64 会在一定程度上增加数据的大小,加密也可能会这样做。正如另一个答案中提到的那样,将其作为二进制文件存储在数据库中在许多方面都更为明智。

(注意:即使您确实想使用该代码,我也会将其写为txt_Last_Name.Text = Encoding.ASCII.GetString(tempByte);。使用指令是您的朋友,并且ASCII是 的属性Encoding,而不是ASCIIEncoding。)

于 2011-01-28T17:15:54.403 回答
0

只是阅读文档......您应该使用Convert.ToBase64String().

于 2011-01-28T17:16:26.297 回答
0

或者 Convert.ToBase64String(),正如上面 pascal 推荐的那样,或者将数据作为二进制而不是文本存储在数据库中(首选解决方案,因为它会使用更少的空间)。在 SQL Server 中,有一个 VARBINARY(MAX) 数据类型用于此目的。

于 2011-01-28T17:18:57.733 回答