Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Шифрование в один класс


Автор: ДобренькийПапаша 22.6.2009, 10:24
Я уже как только не извращался, ничего не получается... Если шифрование и дешифрование в одном классе то всё работает, разношу в разные - не работает (Мне надо в разные)... прошу помощи...

Вот рабочий пример:

Код

namespace SypherDES
{
    class Crypt
    {
        
        static void Main(string[] args)
        {
            string source_str = "Encrypted string";
            Console.WriteLine(source_str);
            byte[] source_data = Encoding.UTF8.GetBytes(source_str);
            DES des = new DESCryptoServiceProvider();
            des.GenerateIV();
            des.GenerateKey();
            byte[] IVByteArray = des.IV;
            byte[] KeyByteArray = des.Key;

            MemoryStream ms_in = new MemoryStream();

            CryptoStream cs_in = new CryptoStream(ms_in,
                des.CreateEncryptor(KeyByteArray, IVByteArray), CryptoStreamMode.Write);
            cs_in.Write(source_data, 0, source_data.Length);
            cs_in.Close();

            string crypt_str = Convert.ToBase64String(ms_in.ToArray());
            Console.WriteLine(crypt_str);

            byte[] crypt_data = Convert.FromBase64String(crypt_str);
            MemoryStream ms_out = new MemoryStream(crypt_data);
            CryptoStream cs_out = new CryptoStream(ms_out,
                des.CreateDecryptor(KeyByteArray, IVByteArray), CryptoStreamMode.Read);

            StreamReader sr_out = new StreamReader(cs_out);
            string source_out = sr_out.ReadToEnd();

            Console.WriteLine(source_out);

            Console.ReadLine();
        }
    }
}

Автор: azesmcar 22.6.2009, 10:33
ДобренькийПапаша

Можно посмотреть пример того, что не работает?

Кстати, base64 это не совсем шифровка. Он не для защиты. Расшировать его может кто угодно.
Это так, на всякий случай.

Автор: ДобренькийПапаша 22.6.2009, 11:02
base64 используется во всех примерах шифрования которые я видел... Скажем если алгоритмом Хеллмана (для безопасной передачи данных) шифровать и передавать в метод только массив байтов, то не знаю как вы будете расшифровывать, не зная секретного ключа...

Вот пример того, что не работает...

Код

namespace SypherDES
{
    class Crypt
    {
        protected DES des = new DESCryptoServiceProvider();
        protected byte[] IVByteArray;
        protected byte[] KeyByteArray;
        public Crypt()
        {
            CreateKeys();
            IVByteArray = des.IV;
            KeyByteArray = des.Key;
        }
        public void CreateKeys()
        {
            des.GenerateIV();
            des.GenerateKey();
        }
        public static string Encrypt(string Password)
        {
            string source_str = Password;
            Console.WriteLine(source_str);
            byte[] source_data = Encoding.UTF8.GetBytes(source_str);
          
            Crypt ex = new Crypt();
            MemoryStream ms_in = new MemoryStream();

            CryptoStream cs_in = new CryptoStream(ms_in,
                ex.des.CreateEncryptor(ex.KeyByteArray, ex.IVByteArray), CryptoStreamMode.Write);
            cs_in.Write(source_data, 0, source_data.Length);
            cs_in.Close();

            string crypt_str = Convert.ToBase64String(ms_in.ToArray());
            Console.WriteLine(crypt_str);
            return crypt_str;
        }
        static void Main(string[] args)
        {
            string EncryptedPassword = "";
            string DecryptedPassword = "";
            EncryptedPassword = Encrypt("12jcnhjd");
            Decrypt ex1 = new Decrypt();
            DecryptedPassword = ex1.DecryptPassword(EncryptedPassword);
            Console.WriteLine(DecryptedPassword);
            Console.ReadLine();
        }
    }

    class Decrypt:Crypt
    {
        public string DecryptPassword(string EncryptedPassword)
        {
            string crypt_str = EncryptedPassword;
            byte[] crypt_data = Convert.FromBase64String(crypt_str);
            MemoryStream ms_out = new MemoryStream(crypt_data);
            CryptoStream cs_out = new CryptoStream(ms_out,
                des.CreateDecryptor(KeyByteArray, IVByteArray), CryptoStreamMode.Read);

            StreamReader sr_out = new StreamReader(cs_out);
            string source_out = sr_out.ReadToEnd();                              //Вот здесь CryptographicException вылетает с надписью "Плохие данные"
                                                                                                          //(довольно частая проблема)
            Console.WriteLine(source_out);
            return source_out;
        }
    }
} 




Под плохими данными он видимо понимает EncryptedPassword и crypt_str (компилятор при дебагге в разделе Locals их значения красным выделяет, их значения как и полагается совпадает)...

(Счас попробую по другому конвертировать)

Я думаю в данном случае проблема в ConvertToBase64 и ConvertFromBase64

Автор: azesmcar 22.6.2009, 11:16
Цитата(ДобренькийПапаша @  22.6.2009,  11:02 Найти цитируемый пост)
base64 используется во всех примерах шифрования которые я видел... Скажем если алгоритмом Хеллмана (для безопасной передачи данных) шифровать и передавать в метод только массив байтов, то не знаю как вы будете расшифровывать, не зная секретного ключа...

http://ru.wikipedia.org/wiki/Base64
У Base64 нет ключа. Я так понял вы шифруете через DES, это нормально. smile 

Цитата(ДобренькийПапаша @  22.6.2009,  11:02 Найти цитируемый пост)
class Decrypt:Crypt

 smile зачем это? class Decrypt наследовать от Crypt?  smile 
Зачем это? Тут наследование совсем не подходит. Что вы хотите сделать конкретно? Упростить шифрование/дешифрование паролей?

Автор: ДобренькийПапаша 22.6.2009, 11:22
Шифрование происходит при создании пароля для юзера, который отправляется в базу...
Дешифруется он из другой формы, и другого класса... ключи как public объявлять я не хочу (ибо это уже на безопасность не похоже будет)

p.s. Да чёрт с ним с наследованием, его я уберу, сделаю свойства, открытые методы, через них ключи получу, вопрос сейчас о другом))))
Просто нужен рабочий пример)))

Автор: azesmcar 22.6.2009, 11:30
Почему бы не написать класс с двумя открытыми статическими функциями Encrypt, Decrypt?

Автор: ДобренькийПапаша 22.6.2009, 11:32
Я Decrypt в форме аутентификации делаю, а Encrypt в форме создания пользователя...

Автор: azesmcar 22.6.2009, 11:33
Код

    class PasswordEncryption
    {
        private static DES CreateCryptoProvider()
        {
            DES des = new DESCryptoServiceProvider();
            des.GenerateIV();
            des.GenerateKey();
            return des;
        }

        public static string Encrypt(string Password)
        {
            DES des = PasswordEncryption.CreateCryptoProvider();
            byte[] IVByteArray = des.IV;
            byte[] KeyByteArray = des.Key;
            string source_str = Password;
            Console.WriteLine(source_str);
            byte[] source_data = Encoding.UTF8.GetBytes(source_str);
            MemoryStream ms_in = new MemoryStream();
            CryptoStream cs_in = new CryptoStream(ms_in,
                des.CreateEncryptor(KeyByteArray, IVByteArray), CryptoStreamMode.Write);
            cs_in.Write(source_data, 0, source_data.Length);
            cs_in.Close();
            string crypt_str = Convert.ToBase64String(ms_in.ToArray());
            Console.WriteLine(crypt_str);
            return crypt_str;
        }

        public string Decrypt(string EncryptedPassword)
        {
            DES des = PasswordEncryption.CreateCryptoProvider();
            byte[] IVByteArray = des.IV;
            byte[] KeyByteArray = des.Key;
            string crypt_str = EncryptedPassword;
            byte[] crypt_data = Convert.FromBase64String(crypt_str);
            MemoryStream ms_out = new MemoryStream(crypt_data);
            CryptoStream cs_out = new CryptoStream(ms_out,
                des.CreateDecryptor(KeyByteArray, IVByteArray), CryptoStreamMode.Read);
            StreamReader sr_out = new StreamReader(cs_out);
            string source_out = sr_out.ReadToEnd();                              //Вот здесь CryptographicException вылетает с надписью "Плохие данные"
            //(довольно частая проблема)
            Console.WriteLine(source_out);
            return source_out;
        }
    }

вот так например.

Добавлено через 17 секунд
Цитата(ДобренькийПапаша @  22.6.2009,  11:32 Найти цитируемый пост)
Я Decrypt в форме аутентификации делаю, а Encrypt в форме создания пользователя... 

Ну и что?

Добавлено через 5 минут и 27 секунд
Код

class PasswordEncryption
    {
        public static string Encrypt(string Password)
        {
            DES des = new DESCryptoServiceProvider();
            des.GenerateIV();
            des.GenerateKey();
            byte[] IVByteArray = des.IV;
            byte[] KeyByteArray = des.Key;
            string source_str = Password;
            Console.WriteLine(source_str);
            byte[] source_data = Encoding.UTF8.GetBytes(source_str);
            MemoryStream ms_in = new MemoryStream();
            CryptoStream cs_in = new CryptoStream(ms_in,
                des.CreateEncryptor(KeyByteArray, IVByteArray), CryptoStreamMode.Write);
            cs_in.Write(source_data, 0, source_data.Length);
            cs_in.Close();
            string crypt_str = Convert.ToBase64String(ms_in.ToArray());
            Console.WriteLine(crypt_str);
            return crypt_str;
        }
    }
    class PasswordDecryption
    {
        public string Decrypt(string EncryptedPassword)
        {
            DES des = new DESCryptoServiceProvider();
            des.GenerateIV();
            des.GenerateKey();
            byte[] IVByteArray = des.IV;
            byte[] KeyByteArray = des.Key;
            string crypt_str = EncryptedPassword;
            byte[] crypt_data = Convert.FromBase64String(crypt_str);
            MemoryStream ms_out = new MemoryStream(crypt_data);
            CryptoStream cs_out = new CryptoStream(ms_out,
                des.CreateDecryptor(KeyByteArray, IVByteArray), CryptoStreamMode.Read);
            StreamReader sr_out = new StreamReader(cs_out);
            string source_out = sr_out.ReadToEnd();                              //Вот здесь CryptographicException вылетает с надписью "Плохие данные"
            //(довольно частая проблема)
            Console.WriteLine(source_out);
            return source_out;
        }
    }

вот, выделил в два разных класса, но я не считаю это хорошей идеей. И вообще - полно дубликатов в коде, надо выделить.

Автор: PashaPash 22.6.2009, 11:43
ДобренькийПапаша, пароли юзеров нельзя шифровать обратимыми алгоритмами. 

Автор: ДобренькийПапаша 22.6.2009, 11:47
Код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace SypherDES
{
    class Crypt
    {
        private static DES des = new DESCryptoServiceProvider();
        private static byte[] IVByteArray;
        private static byte[] KeyByteArray;
       
        public static void CreateKeys()
        {
            des.GenerateIV();
            des.GenerateKey();
            IVByteArray = des.IV;
            KeyByteArray = des.Key;
        }
        public static string Encrypt(string Password)
        {
            string source_str = Password;
            Console.WriteLine(source_str);
            byte[] source_data = Encoding.UTF8.GetBytes(source_str);
            CreateKeys();
            MemoryStream ms_in = new MemoryStream();
            
            CryptoStream cs_in = new CryptoStream(ms_in,
                des.CreateEncryptor(KeyByteArray, IVByteArray), CryptoStreamMode.Write);
            cs_in.Write(source_data, 0, source_data.Length);
            cs_in.Close();

            string crypt_str = Convert.ToBase64String(ms_in.ToArray());
            Console.WriteLine(crypt_str);
            return crypt_str;
        }

        public static string DecryptPassword(string crypt_str)
        {
            byte[] crypt_data = Convert.FromBase64String(crypt_str);
            MemoryStream ms_out = new MemoryStream(crypt_data);
            CryptoStream cs_out = new CryptoStream(ms_out,
                des.CreateDecryptor(KeyByteArray, IVByteArray), CryptoStreamMode.Read);

            StreamReader sr_out = new StreamReader(cs_out);
            string source_out = sr_out.ReadToEnd();
            return source_out;
        }

        static void Main(string[] args)
        {
            string EncryptedPassword = "";
            string DecryptedPassword = "";
            EncryptedPassword = Encrypt("12jcnhjd");
            DecryptedPassword = DecryptPassword(EncryptedPassword);
            Console.WriteLine(DecryptedPassword);
            Console.ReadLine();
         
        }
    }
}


вот так работает...

Мдя... DES признан небезопасным...
Честно говоря я уже замучился...

Автор: azesmcar 22.6.2009, 11:50
Цитата(ДобренькийПапаша @  22.6.2009,  11:47 Найти цитируемый пост)
Мдя... DES признан небезопасным...

Ну да... smile 
Цитата

No easy attack on DES has been discovered, despite the efforts of researchers over many years. The obvious method of attack is a brute-force exhaustive search of the key space; this process takes 2^55 steps on average. Early on, it was suggested [DH77] that a rich and powerful enemy could build a special-purpose computer capable of breaking DES by exhaustive search in a reasonable amount of time. Later, Hellman [Hel80] showed a time-memory tradeoff that allows improvement over exhaustive search if memory space is plentiful. These ideas fostered doubts about the security of DES. There were also accusations the NSA (see Question 6.2.2) had intentionally weakened DES. Despite these suspicions, no feasible way to break DES faster than exhaustive search (see Question 2.4.3) has been discovered. The cost of a specialized computer to perform exhaustive search (requiring 3.5 hours on average) has been estimated by Wiener at one million dollars [Wie94]. This estimate was recently updated by Wiener [Wie98] to give an average time of 35 minutes for the same cost machine. 

а кто защищен от брутфорса?
а зачем вам пароли шифровать? может хэшировать надо? MD5 например.

Цитата(PashaPash @  22.6.2009,  11:43 Найти цитируемый пост)
пароли юзеров нельзя шифровать обратимыми алгоритмами.  

Ну, не то чтобы нельзя. Бывает так, что надо. Но если можно хэшировать (а это большинство случаев) - то лучше хэшировать.

Автор: ДобренькийПапаша 22.6.2009, 11:59
Я нашёл инфу только по DES, RSA, Hellman(не работает в XP)...
RSA мне тоже мозг выносит со своим вылетами "плохие данные"...  http://forum.vingrad.ru/forum/topic-264011.html

У меня  (по поводу ссылки) я там уже много исправил вроде, но там смысл вобщем в том, что "плохие данные"))))

Написал шифрование алгоритмом Хеллмана (лучший вариант), но как выяснилось, что работает сие только в Vista x64 и Windows Server 2008...

Автор: PashaPash 22.6.2009, 16:54
ДобренькийПапаша, может тебе все-таки хэшировать надо? Хэшируешь пароль в форме регистрации. Потом хэшируешь в форме аутентификации. Сопали хэши - совпал пароль. 

Автор: ДобренькийПапаша 22.6.2009, 16:56
Цитата

azesmcar  
Дата 22.6.2009, 11:33
вот, выделил в два разных класса, но я не считаю это хорошей идеей. И вообще - полно дубликатов в коде, надо выделить.


Этот код не работает, и работать вряд ли будет smile 

Автор: PashaPash 22.6.2009, 16:58
Цитата(ДобренькийПапаша @  22.6.2009,  16:56 Найти цитируемый пост)

Этот код не работает, и работать вряд ли будет smile 

В этом явно виноват не код smile

Автор: azesmcar 22.6.2009, 17:08
Цитата(ДобренькийПапаша @  22.6.2009,  16:56 Найти цитируемый пост)
Этот код не работает, и работать вряд ли будет smile  

Ну да, надо еще создать проект, добавить его в пространство имет, откомпилировать...но я бы не стал, может все таки расскажете о задаче? Зачем вам зашифрованный пароль?

Автор: ДобренькийПапаша 22.6.2009, 21:14
Да всё тема закрыта, в Cryptography много что криво реализовано. Во многих алгоритмах такая проблема, что шифровка проходит нормально, а дешифровка нет.

Сделал шифрование через MD5, всё нормально.

А тот код, с DES, задолбаешься дебажить, оно того не стоит. 

Всем спасибо за помощь smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)