2011-01-28 5 views
0

эй, поэтому в базе данных msSQL, которую я сохраняю и извлекаю из использования хранимых процедур. Я пытаюсь зашифровать некоторые данные в форме окна C# перед их размещением, а затем, конечно, расшифровать его, когда я его верну. все шифрование обрабатывается со стороны C#. Я использую пример кода для шифрования и расшифровки дословно из microsoft's tripleDESCryptoService Class (версия памяти, второй пример). Значения зашифровываются и отправляются в базу данных, но при их получении я получаю ошибку «плохих данных». образца вызова шифрования является ...C# tripleDESCrypto сохранено и получено из sql не работает

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, содержащий все нули.

благодарит за любую помощь!

+1

Вы не должны обрабатывать tempByte как строку Unicode, даже не как строку. – pascal

+0

TripleDES считается слабым. Вместо этого вы должны использовать AES :). – ykatchou

ответ

3

EDIT: Ладно, у нас все получилось ... хотя проблема ASCII тоже укусила бы.

Каждый раз, когда вы создаете новый TripleDESCryptoServiceProvider и запрашиваете ключ/IV, он генерирует новый. Вы должны хранить это безопасно где-нибудь, так как это необходимо для расшифровки данных. В противном случае у вас нет какой-либо «секрет», так что это на самом деле не шифрования ...


Это страшная мысль:

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

Вы получили произвольные двоичные данные в tempByte. Не стоит считать действительным текст ASCII. Это почти наверняка, где вы теряете данные.

Используйте Convert.ToBase64String и Convert.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)

+0

Переключая эту историю преобразования байта [] в символы, удивительно количество ошибочных решений, основанных на использовании ASCIIEncoding ... – pascal

+0

@pascal: использование * any * normal Encoding - проблема здесь ... но это обычно ASCII или UTF-8. –

+0

Я предоставил метод шифрования по ссылке, он находится на странице tripleDES от Microsoft ... Страница поставщика в msdn. tempByte был просто для доказательства концепции. я изменил это, избавился от создания массива байтов, а затем проигнорировал его, используя convert.to и from для базы 64. он все еще не работает. угадайте, мне придется попробовать двоичный тип в sql ... –

0

Просто reading the doc ... вы должны преобразовать свой байт [] в строку, используя Convert.ToBase64String().

+0

... и Джон Скит, избивающий меня на 32 секунды, дает аналог: 'Convert.FromBase64String'. – pascal

+0

да, пробовал этот способ конвертации, все равно не работает ... спасибо хотя! –

0

Либо Convert.ToBase64String(), как ранее рекомендованный pascal, либо сохраняйте данные в виде двоичных данных в базе данных вместо текста (предпочтительное решение, так как оно будет использовать меньше места). В SQL Server для этой цели существует тип данных VARBINARY (MAX).

+0

Извините, не заметил, что ответ Джона уже предлагал хранить как двоичный файл. –