Browse Source

增加 AES 加解密方法。

dev
王厅 1 month ago
parent
commit
405be84bda
  1. 135
      Apewer/BytesUtility.cs

135
Apewer/BytesUtility.cs

@ -767,6 +767,17 @@ namespace Apewer
#endregion
#region PKCS #5
/// <summary>使用密码生成密钥。</summary>
static byte[] PKCS5(byte[] password, byte[] salt = null, int iterations = 1000, int bits = 32)
{
var rfc2898 = new Rfc2898DeriveBytes(password, salt, 1);
return rfc2898.GetBytes(32);
}
#endregion
#region AES
private static void Aes256(byte[] key, byte[] salt, Func<RijndaelManaged, ICryptoTransform> create, Stream input, Stream output)
@ -842,6 +853,130 @@ namespace Apewer
return result;
}
private static readonly byte[] AesDefaultIV = new byte[16];
static T UseAes<T>(byte[] key, byte[] iv, CipherMode cipherMode, PaddingMode paddingMode, Func<RijndaelManaged, T> callback)
{
if (key == null) throw new ArgumentNullException(nameof(key));
var keySize = key.Length * 8;
switch (keySize)
{
case 128:
case 192:
case 256:
break;
default:
throw new ArgumentException($"密钥大小【{keySize}】bits 无效。");
}
if (iv == null) iv = AesDefaultIV;
var ivSize = iv.Length * 8;
if (ivSize != 128) throw new ArgumentException($"初始化向量【{ivSize}】bits 无效。");
using (var rijndael = new RijndaelManaged())
{
rijndael.Key = key;
rijndael.IV = iv;
rijndael.Mode = cipherMode;
rijndael.Padding = paddingMode;
return callback.Invoke(rijndael);
}
}
static void UseAes(Stream input, Stream output, byte[] key, byte[] iv, CipherMode cipherMode, PaddingMode paddingMode, Func<RijndaelManaged, ICryptoTransform> create)
{
if (input == null) throw new ArgumentNullException(nameof(input));
if (output == null) throw new ArgumentNullException(nameof(output));
UseAes<object>(key, iv, cipherMode, paddingMode, rijndael =>
{
using (var transformer = create.Invoke(rijndael))
{
using (var stream = new CryptoStream(output, transformer, CryptoStreamMode.Write))
{
Read(input, stream);
stream.Close();
}
}
return null;
});
}
static byte[] UseAes(byte[] input, byte[] key, byte[] iv, CipherMode cipherMode, PaddingMode paddingMode, Func<RijndaelManaged, ICryptoTransform> create)
{
if (input == null) input = new byte[0];
var result = null as byte[];
return UseAes<byte[]>(key, iv, cipherMode, paddingMode, rijndael =>
{
using (var transformer = create.Invoke(rijndael))
{
var result = transformer.TransformFinalBlock(input, 0, input.Length);
return result;
}
});
}
/// <summary>执行 AES 128/192/256 加密。</summary>
/// <param name="plain">明文。</param>
/// <param name="key">密钥。</param>
/// <param name="cipherMode">块密码模式。</param>
/// <param name="paddingMode">填充模式。</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="CryptographicException" />
public static byte[] AesEncrypt(byte[] plain, byte[] key, CipherMode cipherMode = CipherMode.ECB, PaddingMode paddingMode = PaddingMode.PKCS7)
{
return UseAes(plain, key, null, cipherMode, paddingMode, (rijndael) => rijndael.CreateEncryptor(rijndael.Key, rijndael.IV));
}
/// <summary>执行 AES 128/192/256 加密。</summary>
/// <param name="plain">明文。</param>
/// <param name="key">密钥,长度必须是 128 位(16 字节)、192 位(24 字节)或 256 位(32 字节)。</param>
/// <param name="iv">初始化向量,必须是 128 位(16 字节)。</param>
/// <param name="cipherMode">块密码模式。</param>
/// <param name="paddingMode">填充模式。</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="CryptographicException" />
public static byte[] AesEncrypt(byte[] plain, byte[] key, byte[] iv, CipherMode cipherMode = CipherMode.ECB, PaddingMode paddingMode = PaddingMode.PKCS7)
{
return UseAes(plain, key, iv, cipherMode, paddingMode, (rijndael) => rijndael.CreateEncryptor(rijndael.Key, rijndael.IV));
}
/// <summary>执行 AES 128/192/256 解密。</summary>
/// <param name="cipher">密文。</param>
/// <param name="key">密钥,长度必须是 128 位(16 字节)、192 位(24 字节)或 256 位(32 字节)。</param>
/// <param name="cipherMode">块密码模式。</param>
/// <param name="paddingMode">填充模式。</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="CryptographicException" />
public static byte[] AesDecrypt(byte[] cipher, byte[] key, CipherMode cipherMode = CipherMode.ECB, PaddingMode paddingMode = PaddingMode.PKCS7)
{
return UseAes(cipher, key, null, cipherMode, paddingMode, (rijndael) => rijndael.CreateEncryptor(rijndael.Key, rijndael.IV));
}
/// <summary>执行 AES 128/192/256 解密。</summary>
/// <param name="cipher">密文。</param>
/// <param name="key">密钥,长度必须是 128 位(16 字节)、192 位(24 字节)或 256 位(32 字节)。</param>
/// <param name="iv">初始化向量,必须是 128 位(16 字节)。</param>
/// <param name="cipherMode">块密码模式。</param>
/// <param name="paddingMode">填充模式。</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="CryptographicException" />
public static byte[] AesDecrypt(byte[] cipher, byte[] key, byte[] iv, CipherMode cipherMode = CipherMode.ECB, PaddingMode paddingMode = PaddingMode.PKCS7)
{
return UseAes(cipher, key, iv, cipherMode, paddingMode, (rijndael) => rijndael.CreateEncryptor(rijndael.Key, rijndael.IV));
}
#endregion
#region Hash

Loading…
Cancel
Save