国家实名认证使用到的加密
C# 使用BouncyCastle进行AEAD_AES_256_GCM 加密
/// <summary>
/// 使用BouncyCastle进行AEAD_AES_256_GCM 加密
/// </summary>
/// <param name="key">key32位字符</param>
/// <param name="nonce">随机串12位</param>
/// <param name="plainData">明文</param>
/// <param name="associatedData">附加数据可能null</param>
/// <returns></returns>
public static string AesGcmEncryptByBouncyCastleBy(string key, string nonce, string plainData, string associatedData)
{
var associatedBytes = associatedData == null ? null : Encoding.UTF8.GetBytes(associatedData);
byte[] byteData = StrToHexByte(key);
byte[] values = GetRandomBytes(12);
var gcmBlockCipher = new GcmBlockCipher(new AesEngine());
var parameters = new AeadParameters(
new KeyParameter(byteData),
128, //128 = 16 * 8 => (tag size * 8)
Encoding.UTF8.GetBytes(nonce),
associatedBytes);
gcmBlockCipher.Init(true, parameters);
var data = Encoding.UTF8.GetBytes(plainData);
var cipherData = new byte[gcmBlockCipher.GetOutputSize(data.Length)];
var length = gcmBlockCipher.ProcessBytes(data, 0, data.Length, cipherData, 0);
gcmBlockCipher.DoFinal(cipherData, length);
var resutl= Concat(values, cipherData);
return Convert.ToBase64String(resutl);
}
使用BouncyCastle进行AEAD_AES_256_GCM解密
/// <summary>
/// aes-cgm解密
/// </summary>
/// <param name="key"></param>
/// <param name="nonce"></param>
/// <param name="cipherData"></param>
/// <param name="associatedData"></param>
/// <returns></returns>
public static string AesGcmDecryptByBouncyCastle(string key, string nonce, string cipherData, string associatedData)
{
var associatedBytes = associatedData == null ? null : Encoding.UTF8.GetBytes(associatedData);
byte[] byteData = StrToHexByte(key);
var gcmBlockCipher = new GcmBlockCipher(new AesEngine());
byte[] values = GetRandomBytes(12);
var parameters = new AeadParameters(
new KeyParameter(byteData),
128, //128 = 16 * 8 => (tag size * 8)
Encoding.UTF8.GetBytes(nonce),
associatedBytes);
gcmBlockCipher.Init(false, parameters);
var data = Convert.FromBase64String(cipherData);
//去掉前面12个字符
var result = Sub(12, data);
var plaintext = new byte[gcmBlockCipher.GetOutputSize(result.Length)];
var length = gcmBlockCipher.ProcessBytes(result, 0, result.Length, plaintext, 0);
gcmBlockCipher.DoFinal(plaintext, length);
return Encoding.UTF8.GetString(plaintext);
}
公用底层方法
public static byte[] StrToHexByte(string hexString)
{
hexString = hexString.Replace(" ", "");
if ((hexString.Length % 2) != 0)
hexString += " ";
byte[] returnBytes = new byte[hexString.Length / 2];
for (int i = 0; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
return returnBytes;
}
//合并字节
public static byte[] Concat(byte[] a, byte[] b)
{
byte[] output = new byte[a.Length + b.Length];
for (int i = 0; i < a.Length; i++)
{
output[i] = a[i];
}
for (int j = 0; j < b.Length; j++)
{
output[a.Length + j] = b[j];
}
return output;
}
//去掉前面12个字符
public static byte[] Sub(int subNum, byte[] b)
{
byte[] output = new byte[b.Length-subNum];
for (int i = 0; i < b.Length; i++)
{
if (i < subNum)
{
continue;
}
output[i-12] = b[i];
}
return output;
}