.NET Framework
Versleuteling / cryptografie
Zoeken…
Opmerkingen
.NET Framework biedt implementatie van veel cryptografische algoritmen. Ze omvatten in principe symmetrische algoritmen, asymmetrische algoritmen en hashes.
RijndaelManaged
Vereiste naamruimte: 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;
}
}
Gebruik
var textToEncrypt = "hello World";
var encrypted = new Encryption().Encrypt(textToEncrypt); //-> zBmW+FUxOvdbpOGm9Ss/vQ==
var decrypted = new Encryption().Decrypt(encrypted); //-> hello World
Notitie:
- Rijndael is de voorloper van het standaard symmetrische cryptografische algoritme AES.
Gegevens coderen en decoderen met AES (in 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;
}
}
}
Dit voorbeeld is van MSDN .
Het is een demo-toepassing voor de console die laat zien hoe een string kan worden gecodeerd met behulp van de standaard AES- codering en hoe deze achteraf kan worden gedecodeerd.
( AES = Advanced Encryption Standard , een specificatie voor de codering van elektronische gegevens die is opgesteld door het Amerikaanse National Institute of Standards and Technology (NIST) in 2001 en die nog steeds de de facto standaard is voor symmetrische codering)
Opmerkingen:
In een echt coderingsscenario moet u een juiste coderingsmodus kiezen (kan worden toegewezen aan de eigenschap
Mode
door een waarde te selecteren in de inventarisatie vanCipherMode
). Gebruik nooit deCipherMode.ECB
(elektronische codeboekmodus), omdat dit een zwakke codestroom veroorzaaktOm een goede (en geen zwakke)
Key
, gebruikt u een willekeurige cryptografische generator of gebruikt u het bovenstaande voorbeeld ( maak een sleutel van een wachtwoord ). De aanbevolen KeySize is 256 bit. Ondersteunde sleutelgroottes zijn beschikbaar via de eigenschapLegalKeySizes
.Om de initialisatievector
IV
te initialiseren, kunt u een SALT gebruiken zoals in het bovenstaande voorbeeld ( Random SALT )Ondersteunde blokgroottes zijn beschikbaar via de eigenschap
SupportedBlockSizes
, de blokgrootte kan worden toegewezen via de eigenschapBlockSize
Gebruik: zie methode Main ().
Maak een sleutel van een wachtwoord / Random SALT (in 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
}
Dit voorbeeld is afkomstig van MSDN.
Het is een consoledemo en laat zien hoe u een veilige sleutel maakt op basis van een door de gebruiker gedefinieerd wachtwoord en hoe u een willekeurige SALT maakt op basis van de cryptografische willekeurige generator.
Opmerkingen:
De ingebouwde functie
PasswordDeriveBytes
gebruikt het standaard PBKDF1-algoritme om een sleutel uit het wachtwoord te genereren. Standaard gebruikt het 100 iteraties om de sleutel te genereren om brute force-aanvallen te vertragen. De SALT die willekeurig is gegenereerd, versterkt de sleutel verder.De functie
CryptDeriveKey
converteert de sleutel gegenereerd doorPasswordDeriveBytes
naar een sleutel die compatibel is met het opgegeven coderingsalgoritme (hier "TripleDES") met behulp van het opgegeven hash-algoritme (hier "SHA1"). De sleutelgrootte in dit voorbeeld is 192 bytes en de initialisatievector IV is afkomstig van de triple-DES crypto-providerGewoonlijk wordt dit mechanisme gebruikt om een sterkere willekeurig gegenereerde sleutel te beschermen met een wachtwoord, dat een grote hoeveelheid gegevens codeert. U kunt het ook gebruiken om meerdere wachtwoorden van verschillende gebruikers te geven om toegang te geven tot dezelfde gegevens (beschermd door een andere willekeurige sleutel).
Helaas ondersteunt
CryptDeriveKey
momenteel geen AES. Zie hier.
OPMERKING: als oplossing kunt u een willekeurige AES-sleutel maken voor de codering van de gegevens die moeten worden beveiligd met AES en de AES-sleutel opslaan in een TripleDES-container die de sleutel gebruikt die is gegenereerd doorCryptDeriveKey
. Maar dat beperkt de beveiliging tot TripleDES, maakt geen gebruik van de grotere sleutelmaten van AES en creëert een afhankelijkheid van TripleDES.
Gebruik: Zie methode Main ().
Versleuteling en ontsleuteling met behulp van cryptografie (AES)
Decryptiecode
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;
}
Coderingscode
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;
}
Gebruik
var textToEncrypt = "TestEncrypt";
var encrypted = Encrypt(textToEncrypt);
var decrypted = Decrypt(encrypted);