c# TripleDESCrypto 保存并从 sql 检索不工作

发布于 2024-10-14 16:19:04 字数 1298 浏览 2 评论 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 且全为零的数组。

感谢您的帮助!

hey there, so in a msSQL database that i'm saving and retrieving from using stored procedures. i'm trying to encrypt some data in the c# windows form before being placed, and then of course decrypting it when i pull it back. all the encryption is being handled on the c# side. i'm using the sample code for encryption and decryption verbatim from microsoft's tripleDESCryptoService Class (the memory version, 2nd example). The values get encrypted and sent to the database, but when retrieving it i get a "bad data" error.
a sample of the encryption call is...

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);

the txt_Last_Name is then sent to the database, and i can see that there is something in the database. in the database, last name is of type varchar(20)

sample of the decryption call is...

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;

it bombs in the decryption function at: "csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);" and i don't understand why. i'm not sure if it's not getting stored in the database correctly, or my conversions aren't right.

if it means anything, the "Data" coming into the decrypt function is of size 16 and contains non-zero values, but the "byte[] fromEncrypt" is an array of size 16 containing all zeros.

thanks for any help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

英雄似剑 2024-10-21 16:19:04

编辑:好的,我们已经了解了它的底部......尽管 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< /a> 是 Encoding 的属性,而不是 ASCIIEncoding。)

EDIT: Okay, we've got to the bottom of it... although the ASCII issue would have bitten too.

Every time you create a new TripleDESCryptoServiceProvider and ask it for a key/IV, it will generate a new one. You need to store that securely somewhere, as it's required to decrypt the data. Otherwise you don't have any "secret" so it's not really encryption...


This is a terrible idea:

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

You've got arbitrary binary data in tempByte. Don't assume it's valid ASCII text. That's almost certainly where you're losing data.

Use Convert.ToBase64String and Convert.FromBase64String to safely encode opaque binary data as text.

Additionally, this is a bad idea:

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

What's the point of creating a byte array if you're then going to ignore it? Use

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

instead. Oh, and try to follow .NET naming conventions :)

Having said all of this, if your encryption is always returning a byte array of 16 zeroes, that's a pretty sure sign that your encrypt method is broken. We can't really help there until you post the code for that method.

Finally, if your column is of type varchar(20) you should be aware that that may very well not hold all the data you need it to... particularly if you're going to include a salt. Base64 will increase the size of the data somewhat, and encryption may do so too. As mentioned in another answer, storing this as binary in the database would be more sensible in many ways.

(Note: even if you did want to use that code, I'd write it as txt_Last_Name.Text = Encoding.ASCII.GetString(tempByte);. Using directives are your friend, and ASCII is a property of Encoding, not ASCIIEncoding.)

猫卆 2024-10-21 16:19:04

只需阅读文档...您应该使用Convert.ToBase64String()将byte[]转换为字符串。

Just reading the doc... you should convert your byte[] to a String using Convert.ToBase64String().

百善笑为先 2024-10-21 16:19:04

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

Either Convert.ToBase64String(), as pascal recommended above, or store the data as binary in your database instead of text (the preferred solution, since it would use less space). In SQL Server, there is a VARBINARY(MAX) data type for this very purpose.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文