.NET Framework
Шифрование / криптография
Поиск…
замечания
.NET Framework обеспечивает реализацию многих криптографических алгоритмов. Они включают в себя в основном симметричные алгоритмы, асимметричные алгоритмы и хеши.
RijndaelManaged
Требуемое пространство имен: System.Security.Cryptography
private class Encryption {
private const string SecretKey = "topSecretKeyusedforEncryptions";
private const string SecretIv = "secretVectorHere";
public string Encrypt(string data) {
return string.IsNullOrEmpty(data) ? data : Convert.ToBase64String(this.EncryptStringToBytesAes(data, this.GetCryptographyKey(), this.GetCryptographyIv()));
}
public string Decrypt(string data) {
return string.IsNullOrEmpty(data) ? data : this.DecryptStringFromBytesAes(Convert.FromBase64String(data), this.GetCryptographyKey(), this.GetCryptographyIv());
}
private byte[] GetCryptographyKey() {
return Encoding.ASCII.GetBytes(SecretKey.Replace('e', '!'));
}
private byte[] GetCryptographyIv() {
return Encoding.ASCII.GetBytes(SecretIv.Replace('r', '!'));
}
private byte[] EncryptStringToBytesAes(string plainText, byte[] key, byte[] iv) {
MemoryStream encrypt;
RijndaelManaged aesAlg = null;
try {
aesAlg = new RijndaelManaged {
Key = key,
IV = iv
};
var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
encrypt = new MemoryStream();
using (var csEncrypt = new CryptoStream(encrypt, encryptor, CryptoStreamMode.Write)) {
using (var swEncrypt = new StreamWriter(csEncrypt)) {
swEncrypt.Write(plainText);
}
}
} finally {
aesAlg?.Clear();
}
return encrypt.ToArray();
}
private string DecryptStringFromBytesAes(byte[] cipherText, byte[] key, byte[] iv) {
RijndaelManaged aesAlg = null;
string plaintext;
try {
aesAlg = new RijndaelManaged {
Key = key,
IV = iv
};
var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
using (var msDecrypt = new MemoryStream(cipherText)) {
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) {
using (var srDecrypt = new StreamReader(csDecrypt))
plaintext = srDecrypt.ReadToEnd();
}
}
} finally {
aesAlg?.Clear();
}
return plaintext;
}
}
использование
var textToEncrypt = "hello World";
var encrypted = new Encryption().Encrypt(textToEncrypt); //-> zBmW+FUxOvdbpOGm9Ss/vQ==
var decrypted = new Encryption().Decrypt(encrypted); //-> hello World
Замечания:
- Rijndael является предшественником стандартного симметричного криптографического алгоритма AES.
Шифровать и расшифровывать данные с использованием AES (в C #)
using System;
using System.IO;
using System.Security.Cryptography;
namespace Aes_Example
{
class AesExample
{
public static void Main()
{
try
{
string original = "Here is some data to encrypt!";
// Create a new instance of the Aes class.
// This generates a new key and initialization vector (IV).
using (Aes myAes = Aes.Create())
{
// Encrypt the string to an array of bytes.
byte[] encrypted = EncryptStringToBytes_Aes(original,
myAes.Key,
myAes.IV);
// Decrypt the bytes to a string.
string roundtrip = DecryptStringFromBytes_Aes(encrypted,
myAes.Key,
myAes.IV);
//Display the original data and the decrypted data.
Console.WriteLine("Original: {0}", original);
Console.WriteLine("Round Trip: {0}", roundtrip);
}
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
}
}
static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
byte[] encrypted;
// Create an Aes object with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key,
aesAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt,
encryptor,
CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
}
static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
// Declare the string used to hold the decrypted text.
string plaintext = null;
// Create an Aes object with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key,
aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt,
decryptor,
CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
}
}
Этот пример из MSDN .
Это консольное демонстрационное приложение, показывающее, как шифровать строку, используя стандартное шифрование AES , и как расшифровать ее впоследствии.
( AES = Advanced Encryption Standard , спецификация для шифрования электронных данных, установленная Национальным институтом стандартов и технологий США (NIST) в 2001 году, которая по-прежнему является стандартом де-факто для симметричного шифрования)
Заметки:
В реальном сценарии шифрования вам необходимо выбрать правильный режим шифрования (его можно присвоить свойству «
Mode
», выбрав значение из перечисленияCipherMode
). Никогда не используйтеCipherMode.ECB
(режим электронной кодовой книги), так как это обеспечивает слабый поток шифровЧтобы создать хороший (а не слабый)
Key
, используйте криптографический случайный генератор или используйте пример выше ( Create a Key from the Password ). Рекомендуемый KeySize - 256 бит. Поддерживаемые размеры ключей доступны через свойствоLegalKeySizes
.Чтобы инициализировать вектор инициализации
IV
, вы можете использовать СОЛЬ, как показано в примере выше ( Random SALT )Поддерживаемые размеры блоков доступны через свойство
SupportedBlockSizes
, размер блока может быть назначен через свойствоBlockSize
Использование: см. Метод Main ().
Создайте ключ из пароля / случайного СОЛЬ (в C #)
using System;
using System.Security.Cryptography;
using System.Text;
public class PasswordDerivedBytesExample
{
public static void Main(String[] args)
{
// Get a password from the user.
Console.WriteLine("Enter a password to produce a key:");
byte[] pwd = Encoding.Unicode.GetBytes(Console.ReadLine());
byte[] salt = CreateRandomSalt(7);
// Create a TripleDESCryptoServiceProvider object.
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
try
{
Console.WriteLine("Creating a key with PasswordDeriveBytes...");
// Create a PasswordDeriveBytes object and then create
// a TripleDES key from the password and salt.
PasswordDeriveBytes pdb = new PasswordDeriveBytes(pwd, salt);
// Create the key and set it to the Key property
// of the TripleDESCryptoServiceProvider object.
tdes.Key = pdb.CryptDeriveKey("TripleDES", "SHA1", 192, tdes.IV);
Console.WriteLine("Operation complete.");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
// Clear the buffers
ClearBytes(pwd);
ClearBytes(salt);
// Clear the key.
tdes.Clear();
}
Console.ReadLine();
}
#region Helper methods
/// <summary>
/// Generates a random salt value of the specified length.
/// </summary>
public static byte[] CreateRandomSalt(int length)
{
// Create a buffer
byte[] randBytes;
if (length >= 1)
{
randBytes = new byte[length];
}
else
{
randBytes = new byte[1];
}
// Create a new RNGCryptoServiceProvider.
RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider();
// Fill the buffer with random bytes.
rand.GetBytes(randBytes);
// return the bytes.
return randBytes;
}
/// <summary>
/// Clear the bytes in a buffer so they can't later be read from memory.
/// </summary>
public static void ClearBytes(byte[] buffer)
{
// Check arguments.
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
// Set each byte in the buffer to 0.
for (int x = 0; x < buffer.Length; x++)
{
buffer[x] = 0;
}
}
#endregion
}
Этот пример взят из MSDN.
Это демонстрация консоли, в которой показано, как создать защищенный ключ на основе пользовательского пароля и как создать произвольную ОСВ на основе криптографического генератора.
Заметки:
Встроенная функция
PasswordDeriveBytes
использует стандартный алгоритм PBKDF1 для генерации ключа из пароля. По умолчанию он использует 100 итераций для генерации ключа, чтобы замедлить атаки грубой силы. Соль, генерируемая случайным образом, еще более укрепляет ключ.Функция
CryptDeriveKey
преобразует ключ, сгенерированныйPasswordDeriveBytes
в ключ, совместимый с указанным алгоритмом шифрования (здесь «TripleDES»), используя указанный хэш-алгоритм (здесь «SHA1»). Ключ в этом примере составляет 192 байта, а вектор инициализации IV берется у поставщика криптографии с тройным DESОбычно этот механизм используется для защиты более сильного случайного сгенерированного ключа паролем, который шифрует большой объем данных. Вы также можете использовать его для предоставления нескольких паролей разных пользователей для доступа к тем же данным (их защищает другой случайный ключ).
К сожалению,
CryptDeriveKey
настоящее время не поддерживает AES. См. Здесь.
ПРИМЕЧАНИЕ. В качестве обходного пути вы можете создать случайный ключ AES для шифрования данных, которые должны быть защищены AES, и сохранить ключ AES в TripleDES-контейнере, который использует ключ, сгенерированныйCryptDeriveKey
. Но это ограничивает безопасность TripleDES, не использует преимущества больших ключей AES и создает зависимость от TripleDES.
Использование: см. Метод Main ().
Шифрование и дешифрование с использованием криптографии (AES)
Код дешифрования
public static string Decrypt(string cipherText)
{
if (cipherText == null)
return null;
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(CryptKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
Код шифрования
public static string Encrypt(string cipherText)
{
if (cipherText == null)
return null;
byte[] clearBytes = Encoding.Unicode.GetBytes(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(CryptKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
cipherText = Convert.ToBase64String(ms.ToArray());
}
}
return cipherText;
}
использование
var textToEncrypt = "TestEncrypt";
var encrypted = Encrypt(textToEncrypt);
var decrypted = Decrypt(encrypted);