Очень простое шифрование с помощью C# и SymmetricAlgorithm
Я ищу очень простых метода шифрования / дешифрования. Я буду использовать всегда один и тот же статический ключ. Я знаю о рисках такого подхода. В настоящее время я использую следующий код, но он не генерирует тот же результат после шифрования и декрипции той же строки (есть некоторый мусор в середине строки).
public static string Crypt(this string text)
{
string result = null;
if (!String.IsNullOrEmpty(text))
{
byte[] plaintextBytes = Encoding.Unicode.GetBytes(text);
SymmetricAlgorithm symmetricAlgorithm = DES.Create();
symmetricAlgorithm.Key = new byte[8] {1, 2, 3, 4, 5, 6, 7, 8};
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, symmetricAlgorithm.CreateEncryptor(), CryptoStreamMode.Write))
{
cryptoStream.Write(plaintextBytes, 0, plaintextBytes.Length);
}
result = Encoding.Unicode.GetString(memoryStream.ToArray());
}
}
return result;
}
public static string Decrypt(this string text)
{
string result = null;
if (!String.IsNullOrEmpty(text))
{
byte[] encryptedBytes = Encoding.Unicode.GetBytes(text);
SymmetricAlgorithm symmetricAlgorithm = DES.Create();
symmetricAlgorithm.Key = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream memoryStream = new MemoryStream(encryptedBytes))
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, symmetricAlgorithm.CreateDecryptor(), CryptoStreamMode.Read))
{
byte[] decryptedBytes = new byte[encryptedBytes.Length];
cryptoStream.Read(decryptedBytes, 0, decryptedBytes.Length);
result = Encoding.Unicode.GetString(decryptedBytes);
}
}
}
return result;
}
Я могу изменить все, что нужно, без ограничений (но я хочу просто иметь метод шифрования и другой для расшифровки без совместное использование переменных между ними).
спасибо.
3 ответов
если вы не хотите обрабатывать ключи самостоятельно, то пусть операционная система сделает это за вас. Е. Г. используйте Защита Данных Windows (интерфейс dpapi).
вы можете написать свой собственный, string
- based, версия System.Security.Cryptography.ProtectedData.Protect
и Unprotect
методы, используя что-то вроде:
public static string Crypt (this string text)
{
return Convert.ToBase64String (
ProtectedData.Protect (
Encoding.Unicode.GetBytes (text) ) );
}
public static string Derypt (this string text)
{
return Encoding.Unicode.GetString (
ProtectedData.Unprotect (
Convert.FromBase64String (text) ) );
}
Как насчет чего-то вроде этого?
код
using System;
using System.Security.Cryptography;
using System.Text;
public static class StringUtil
{
private static byte[] key = new byte[8] {1, 2, 3, 4, 5, 6, 7, 8};
private static byte[] iv = new byte[8] {1, 2, 3, 4, 5, 6, 7, 8};
public static string Crypt(this string text)
{
SymmetricAlgorithm algorithm = DES.Create();
ICryptoTransform transform = algorithm.CreateEncryptor(key, iv);
byte[] inputbuffer = Encoding.Unicode.GetBytes(text);
byte[] outputBuffer = transform.TransformFinalBlock(inputbuffer, 0, inputbuffer.Length);
return Convert.ToBase64String(outputBuffer);
}
public static string Decrypt(this string text)
{
SymmetricAlgorithm algorithm = DES.Create();
ICryptoTransform transform = algorithm.CreateDecryptor(key, iv);
byte[] inputbuffer = Convert.FromBase64String(text);
byte[] outputBuffer = transform.TransformFinalBlock(inputbuffer, 0, inputbuffer.Length);
return Encoding.Unicode.GetString(outputBuffer);
}
}
Единица Теста
[Test]
public void Test()
{
string expected = "this is my test string";
string a = expected.Crypt();
Debug.WriteLine(a);
string actual = a.Decrypt();
Assert.AreEqual(expected, actual);
}
EDIT:
чтобы уточнить: я знаю, что это не хорошая практика.
вам нужно будет установить режим шифрования в CipherMode.ЕЦБ или используйте IV.
SymmetricAlgorithm symmetricAlgorithm = DES.Create();
symmetricAlgorithm.Key = new byte[8] { 1, 2, 3, 4, 5, 6, 7, 8 };
symmetricAlgorithm.Mode = CipherMode.ECB;
...
другой момент - не использовать кодировку Unicode. Вместо этого используйте Base64. Unicode может "уничтожить" байты, которые не являются UTF-16.