using System;
using System.Security.Cryptography;
namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities
{
using SKIT.FlurlHttpClient.Primitives;
///
/// AES 算法工具类。
///
public static class AESUtility
{
///
/// 基于 CBC 模式解密数据。
///
/// AES 密钥字节数组。
/// 加密使用的初始化向量字节数组。
/// 待解密数据字节数组。
/// 解密后的数据字节数组。
public static byte[] DecryptWithCBC(byte[] keyBytes, byte[] ivBytes, byte[] cipherBytes)
{
if (keyBytes is null) throw new ArgumentNullException(nameof(keyBytes));
if (ivBytes is null) throw new ArgumentNullException(nameof(ivBytes));
if (cipherBytes is null) throw new ArgumentNullException(nameof(cipherBytes));
using (SymmetricAlgorithm aes = Aes.Create())
{
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.Key = keyBytes;
aes.IV = ivBytes;
using ICryptoTransform transform = aes.CreateDecryptor();
return transform.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);
}
}
///
/// 基于 CBC 模式解密数据。
///
/// 经过编码后的(通常为 Base64)AES 密钥。
/// 经过编码后的(通常为 Base64)初始化向量。
/// 经过编码后的(通常为 Base64)待解密数据。
/// 解密后的数据。
public static EncodedString DecryptWithCBC(EncodedString encodingKey, EncodedString encodingIV, EncodedString encodingCipher)
{
if (encodingKey.Value is null) throw new ArgumentNullException(nameof(encodingKey));
if (encodingIV.Value is null) throw new ArgumentNullException(nameof(encodingIV));
if (encodingCipher.Value is null) throw new ArgumentNullException(nameof(encodingCipher));
byte[] plainBytes = DecryptWithCBC(
keyBytes: EncodedString.FromString(encodingKey, fallbackEncodingKind: EncodingKinds.Base64),
ivBytes: EncodedString.FromString(encodingIV, fallbackEncodingKind: EncodingKinds.Base64),
cipherBytes: EncodedString.FromString(encodingCipher, fallbackEncodingKind: EncodingKinds.Base64)
);
return EncodedString.ToLiteralString(plainBytes);
}
///
/// 基于 CBC 模式加密数据。
///
/// AES 密钥字节数组。
/// 加密使用的初始化向量字节数组。
/// 待加密数据字节数组。
/// 加密后的数据字节数组。
public static byte[] EncryptWithCBC(byte[] keyBytes, byte[] ivBytes, byte[] plainBytes)
{
if (keyBytes is null) throw new ArgumentNullException(nameof(keyBytes));
if (ivBytes is null) throw new ArgumentNullException(nameof(ivBytes));
if (plainBytes is null) throw new ArgumentNullException(nameof(plainBytes));
using (SymmetricAlgorithm aes = Aes.Create())
{
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.Key = keyBytes;
aes.IV = ivBytes;
using ICryptoTransform transform = aes.CreateEncryptor();
return transform.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
}
}
///
/// 基于 CBC 模式加密数据。
///
/// 经过编码后的(通常为 Base64)AES 密钥。
/// 经过编码后的(通常为 Base64)初始化向量。
/// 待加密数据。
/// 经过 Base64 编码的加密后的数据。
public static EncodedString EncryptWithCBC(EncodedString encodingKey, EncodedString encodingIV, string plainData)
{
if (encodingKey.Value is null) throw new ArgumentNullException(nameof(encodingKey));
if (encodingIV.Value is null) throw new ArgumentNullException(nameof(encodingIV));
if (plainData is null) throw new ArgumentNullException(nameof(plainData));
byte[] plainBytes = EncryptWithCBC(
keyBytes: EncodedString.FromString(encodingKey, fallbackEncodingKind: EncodingKinds.Base64),
ivBytes: EncodedString.FromString(encodingIV, fallbackEncodingKind: EncodingKinds.Base64),
plainBytes: EncodedString.FromLiteralString(plainData)
);
return EncodedString.ToBase64String(plainBytes);
}
}
}