C#: Как закриптовать что-нибудь хоть как-нибудь

IT IT
Как известно, принцип "мы с Томарой ходим парой" весьма распространён в различных API, нужно не просто знать какие методы вызывать, но и в какой последовательности. В MSDN много примеров как закриптовать целый файл. Но, к сожалению, нет ничего о том как закриптовать просто строку или массив байт. Следующий класс позволяет восполнить данный пробел.

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

namespace RSDN
{
    public class Crypt
    {
        public static byte[] Encrypt(byte[] data,string password)
        {
            SymmetricAlgorithm sa = Rijndael.Create();
            ICryptoTransform ct = sa.CreateEncryptor(
                (new PasswordDeriveBytes(password,null)).GetBytes(16),
                new byte[16]);

            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms,ct,CryptoStreamMode.Write);

            cs.Write(data,0,data.Length);
            cs.FlushFinalBlock();

            return ms.ToArray();
        }

        public static string Encrypt(string data,string password)
        {
            return Convert.ToBase64String(Encrypt(Encoding.UTF8.GetBytes(data),password));
        }

        static public byte[] Decrypt(byte[] data,string password)
        {
            BinaryReader br = new BinaryReader(InternalDecrypt(data,password));
            return br.ReadBytes((int)br.BaseStream.Length);
        }

        static public string Decrypt(string data,string password)
        {
            CryptoStream cs = InternalDecrypt(Convert.FromBase64String(data),password);
            StreamReader sr = new StreamReader(cs);
            return sr.ReadToEnd();
        }

        static CryptoStream InternalDecrypt(byte[] data,string password)
        {
            SymmetricAlgorithm sa = Rijndael.Create();
            ICryptoTransform ct = sa.CreateDecryptor(
                (new PasswordDeriveBytes(password,null)).GetBytes(16),
                new byte[16]);

            MemoryStream ms = new MemoryStream(data);
            return new CryptoStream(ms,ct,CryptoStreamMode.Read);
        }
    }
}
Vampire
Vampire
27.08.2002 07:32
Здравствуйте IT, Вы писали:

IT>Как известно, принцип "мы с Томарой ходим парой" весьма распространён в различных API, нужно не просто знать какие методы вызывать, но и в какой последовательности. В MSDN много примеров как закриптовать целый файл. Но, к сожалению, нет ничего о том как закриптовать просто строку или массив байт. Следующий класс позволяет восполнить данный пробел.


А как это дело на C# в dll засунуть. Для использования на C++. А лучше вообще в COM.
Можно это как-то просто сделать ?
IT
IT
27.08.2002 01:16
Здравствуйте Vampire, Вы писали:

V>А как это дело на C# в dll засунуть. Для использования на C++. А лучше вообще в COM.

V>Можно это как-то просто сделать ?

http://www.rsdn.ru/article/?dotnet/net2com.xml
mikа
mikа
21.07.2004 11:15
Здравствуйте, IT, Вы писали:

IT>В MSDN много примеров как закриптовать целый файл. Но, к сожалению, нет ничего о том как закриптовать просто строку или массив байт.


  1. Если уж работаешь со строками (входные данные при кодировании), то и пусть результат будет тоже строкой.
  2. Файл есть Stream. Класс MemoryStream (с объектом которого ты работаешь) является его наследником. Тоесть, MSDN: Stream -> Encrypt -> Decrypt -> Stream. Твой класс: String -> Raw Bytes -> Stream -> Encrypt -> Decrypt -> Stream -> Raw Bytes -> String
  3. Посмотри на GDN класс для шифрации Remoting траффика. Основная идея того класса, что нет жесткой привязки к алгоритму шифрации (например, нет явного использования Rijndael) и алгоритмы не иниицализируються по паролю (PasswordDeriveBytes).
IT
IT
21.07.2004 11:37
Здравствуйте, mikа, Вы писали:

M>Если уж работаешь со строками...


Ну так давай, вперёд, улучшай
mikа
mikа
21.07.2004 11:48
Здравствуйте, IT, Вы писали:

IT>Ну так давай, вперёд, улучшай


Еще немного покритикую

  1. static public string Decrypt(string data,string password)

    public static string Encrypt(string data,string password)

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

  2. Если объявляешь класс только со статическими мемберами, то: объяви его как sealed и реализую private конструктор
IT
IT
21.07.2004 12:20
Здравствуйте, mikа, Вы писали:

M>Имеется ли тайный смысл перестановки этих кейвордов? Наверное, лучше идти по единообразию.


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

M>Если объявляешь класс только со статическими мемберами, то: объяви его как sealed и реализую private конструктор


А вдруг у меня появится желание от него наследоваться?

mikа
mikа
21.07.2004 12:23
Здравствуйте, IT, Вы писали:

M>>Имеется ли тайный смысл перестановки этих кейвордов? Наверное, лучше идти по единообразию.


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


Это шутка?
IT
IT
21.07.2004 01:51
Здравствуйте, mikа, Вы писали:

M>>>Имеется ли тайный смысл перестановки этих кейвордов? Наверное, лучше идти по единообразию.


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


M> Это шутка?


Ты имеешь ввиду свой вопрос?
mikа
mikа
21.07.2004 02:08
Здравствуйте, IT, Вы писали:

IT>Ты имеешь ввиду свой вопрос?


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

mikа
mikа
21.07.2004 07:13
Здравствуйте, IT, Вы писали:

Самое сильное, чего просто не могут терпеть фибры моей души, так это захардкоденные значения.

SymmetricAlgorithm sa = Rijndael.Create();
ICryptoTransform ct = sa.CreateEncryptor((new PasswordDeriveBytes(password,null)).GetBytes( 16 ), new byte[ 16 ]);


Выносите их в отдельные константы.
Styx_
Styx_
20.09.2005 08:41
Здравствуйте, IT, Вы писали:

IT>Как известно, принцип "мы с Томарой ходим парой" весьма распространён в различных API, нужно не просто знать какие методы вызывать, но и в какой последовательности. В MSDN много примеров как закриптовать целый файл. Но, к сожалению, нет ничего о том как закриптовать просто строку или массив байт. Следующий класс позволяет восполнить данный пробел.


IT>
IT>using System;
IT>using System.IO;
IT>using System.Text;
IT>using System.Security.Cryptography;

IT>namespace RSDN
IT>{
IT>    public class Crypt
IT>    {
IT>        public static byte[] Encrypt(byte[] data,string password)
IT>        {
IT>            SymmetricAlgorithm sa = Rijndael.Create();
IT>            ICryptoTransform ct = sa.CreateEncryptor(
IT>                (new PasswordDeriveBytes(password,null)).GetBytes(16),
IT>                new byte[16]);

IT>            MemoryStream ms = new MemoryStream();
IT>            CryptoStream cs = new CryptoStream(ms,ct,CryptoStreamMode.Write);

IT>            cs.Write(data,0,data.Length);
IT>            cs.FlushFinalBlock();

IT>            return ms.ToArray();
IT>        }

IT>        public static string Encrypt(string data,string password)
IT>        {
IT>            return Convert.ToBase64String(Encrypt(Encoding.UTF8.GetBytes(data),password));
IT>        }

IT>        static public byte[] Decrypt(byte[] data,string password)
IT>        {
IT>            BinaryReader br = new BinaryReader(InternalDecrypt(data,password));
IT>            return br.ReadBytes((int)br.BaseStream.Length);
IT>        }

IT>        static public string Decrypt(string data,string password)
IT>        {
IT>            CryptoStream cs = InternalDecrypt(Convert.FromBase64String(data),password);
IT>            StreamReader sr = new StreamReader(cs);
IT>            return sr.ReadToEnd();
IT>        }

IT>        static CryptoStream InternalDecrypt(byte[] data,string password)
IT>        {
IT>            SymmetricAlgorithm sa = Rijndael.Create();
IT>            ICryptoTransform ct = sa.CreateDecryptor(
IT>                (new PasswordDeriveBytes(password,null)).GetBytes(16),
IT>                new byte[16]);

IT>            MemoryStream ms = new MemoryStream(data);
IT>            return new CryptoStream(ms,ct,CryptoStreamMode.Read);
IT>        }
IT>    }
IT>}
IT>


Еслиб ты ещё написал как всем этим воспользоватся. Было бы круто
ArtDenis
ArtDenis
22.08.2006 07:08
Здравствуйте, Styx_, Вы писали:

S_>Еслиб ты ещё написал как всем этим воспользоватся. Было бы круто


Неужели непонятно? Пользоваться этим вот так
... << RSDN@Home 1.1.4 stable rev. 510>>
ВМоисеев
ВМоисеев
27.08.2006 08:21
Здравствуйте, Styx_, Вы писали:

S_>Здравствуйте, IT, Вы писали:



S_>Еслиб ты ещё написал как всем этим воспользоватся. Было бы круто


Посмотри здесь: http://www.gotdotnet.ru/LearnDotNet/NETFramework/223738.aspx
Dmitriy Dubrovskiy
Dmitriy Dubrovskiy Валимся по исключению
21.08.2006 05:34
Тест .Net Framework 2.0:

            byte[] buf = new byte[] {0x33, 0x35, 0x36 };
            byte[] b1 = Crypt.Encrypt(buf, "t");

            buffer = Crypt.Decrypt(b1, "t");


Исключение:

System.NotSupportedException was caught
Stream does not support seeking.

Сторока, где оно возникает:

        static public byte[] Decrypt(byte[] data, string password)
        {
            BinaryReader br = new BinaryReader(InternalDecrypt(data,password));
            br.BaseStream.Seek(0, SeekOrigin.Begin);                   //  <=== Stream does not support seeking.
            return br.ReadBytes((int)br.BaseStream.Length);
        }
Daimond
Daimond
27.08.2006 06:32
Здравствуйте, Dmitriy Dubrovskiy, Вы писали:

Ощибка в предыдузем посте.
Валимся здесь:


       static public byte[] Decrypt(byte[] data, string password)
       {
           BinaryReader br = new BinaryReader(InternalDecrypt(data,password));
           return br.ReadBytes((int)br.BaseStream.Length);//  <=== Stream does not support seeking.
       }
gravatar
Аноним
21.01.2007 11:02
Здравствуйте, Daimond, Вы писали:

D>Здравствуйте, Dmitriy Dubrovskiy, Вы писали:


D>Ощибка в предыдузем посте.

D>Валимся здесь:


D>
D>       static public byte[] Decrypt(byte[] data, string password)
D>       {
D>           BinaryReader br = new BinaryReader(InternalDecrypt(data,password));
D>           return br.ReadBytes((int)br.BaseStream.Length);//  <=== Stream does not support seeking.
D>       }
D>



Свойство Length у данного Stream оставленно только для совместимости при наследовании. В MSDN прописано.
Заменяем:

static public byte[] Decrypt(byte[] data,string password)
{
BinaryReader br = new BinaryReader(InternalDecrypt(data,password));
return br.ReadBytes(data.Length);
}
gravatar
Аноним
02.02.2007 03:48
Здравствуйте, IT, Вы писали:

IT>Как известно, принцип "мы с Томарой ходим парой" весьма распространён в различных API, нужно не просто знать какие методы вызывать, но и в какой последовательности. В MSDN много примеров как закриптовать целый файл. Но, к сожалению, нет ничего о том как закриптовать просто строку или массив байт. Следующий класс позволяет восполнить данный пробел.


а каким способом можно соединять закриптованные строки без вреда информации? есть ли символ, который с точностью 100% не появится в шифрованной строке?
IT
IT
02.02.2007 04:07
Здравствуйте, <Аноним>, Вы писали:

А>а каким способом можно соединять закриптованные строки без вреда информации? есть ли символ, который с точностью 100% не появится в шифрованной строке?


Не знаю. Но с помощью замены такой символ можно всегда сделать самому.
... << RSDN@Home 1.2.0 alpha rev. 0>>