.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 、 2001年に米国国立標準技術研究所(NIST)によって確立された電子データの暗号化仕様であり、依然として対称暗号化のデファクトスタンダードである)
ノート:
実際の暗号化シナリオでは、適切な暗号モードを選択する必要があります(
CipherMode
列挙から値を選択することによって、Mode
プロパティに割り当てることができます)。CipherMode.ECB
(電子コードブックモード)を使用しないでください。これは弱いサイファーストリームを生成するためです良い(弱くない)
Key
を作成するには、暗号乱数生成器を使用するか、上記の例( パスワードから鍵を作成する )を使用してください。推奨KeySizeは256ビットです。サポートされているキーのサイズは、LegalKeySizes
プロパティからLegalKeySizes
ます。初期化ベクトル
IV
を初期化するには、上記の例( Random SALT )のようにSALTを使用し、サポートされているブロックサイズは
SupportedBlockSizes
プロパティで利用でき、ブロックサイズはBlockSize
プロパティで割り当てることができます
使用方法: Main()メソッドを参照してください。
パスワード/ランダムSALTからキーを作成する(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
}
これはコンソールのデモであり、ユーザー定義のパスワードに基づいて安全な鍵を作成する方法と、暗号ランダム生成プログラムに基づいてランダムなSALTを作成する方法を示しています。
ノート:
組み込み関数
PasswordDeriveBytes
は、標準のPBKDF1アルゴリズムを使用してパスワードからキーを生成します。デフォルトでは、100回の反復を使用して鍵を生成し、ブルートフォース攻撃を減速させます。生成されたSALTは、キーをさらにランダムに生成します。関数
CryptDeriveKey
は、指定されたハッシュアルゴリズム(ここでは "SHA1")を使用して、PasswordDeriveBytes
によって生成されたキーを指定された暗号化アルゴリズム(ここでは "TripleDES")と互換性のあるキーに変換します。この例のkeysizeは192バイトで、初期化ベクトルIVはトリプルDES暗号化プロバイダから取得されます通常、このメカニズムは、大量のデータを暗号化するパスワードによってランダムに生成された強力な鍵を保護するために使用されます。また、異なるユーザーの複数のパスワードを提供して、同じデータ(別のランダムキーで保護されている)にアクセスすることもできます。
残念ながら、
CryptDeriveKey
は現在AESをサポートしていません。 ここを参照してください。
注記:回避策として、AESで保護するデータを暗号化するランダムAESキーを作成し、CryptDeriveKey
生成されたキーを使用するTripleDESコンテナにAESキーを格納することが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);