C# 中的 AEAD_AES_256_GCM
- 注意:AEAD_AES_256_GCM Key的长度必须是32位,nonce的长度必须是12位,附加数据有可能为空值。AEAD_AES_128_GCM Key的长度必须是16位,nonce的长度必须是12位,附加数据有可能为空值。
使用中AEAD_AES_256_GCM还是AEAD_AES_128_GCM加密,是根据key的长度来决定的。
size = key.Length * 8
256 = 32 * 8, AEAD_AES_256_GCM的key长度必须是 32 位。
128 = 16 * 8, AEAD_AES_128_GCM的key长度必须是 16 位。
英文好的可以看这个文档rfc5116
使用官方AesGcm类
自aspnetcore3.0之后,System.Security.Cryptography支持 AES_GCM,不支持.net framework。在加密时,请使用AesGcmEncryptToBase64_WithTag方法,这个方法的结果包含了tag (authentication tag)。加密结果最后面的16位字符就是tag,但是官方的加密方法没有帮我们拼接上。
/// <summary>
/// 使用 AesGcm 解密
/// </summary>
/// <param name="key">key32位字符</param>
/// <param name="nonce">随机串12位</param>
/// <param name="encryptedData">密文(Base64字符)</param>
/// <param name="associatedData">(可能null)</param>
/// <returns></returns>
static string AesGcmDecryptFromBase64(string key, string nonce, string encryptedData, string associatedData)
{
var keyBytes = Encoding.UTF8.GetBytes(key);
var nonceBytes = Encoding.UTF8.GetBytes(nonce);
var associatedBytes = associatedData == null ? null : Encoding.UTF8.GetBytes(associatedData); var encryptedBytes = Convert.FromBase64String(encryptedData);
//tag size is 16
var cipherBytes = encryptedBytes[..^16];
var tag = encryptedBytes[^16..];
var decryptedData = new byte[cipherBytes.Length];
using var cipher = new AesGcm(keyBytes);
cipher.Decrypt(nonceBytes, cipherBytes, tag, decryptedData, associatedBytes);
return Encoding.UTF8.GetString(decryptedData);
} /// <summary>
/// 使用 AesGcm AEAD_AES_256_GCM 加密,不要在正式环境中使用这个方法。因为在解密时不知道tag,除非额外返回tag。
/// </summary>
/// <param name="key">key32位字符</param>
/// <param name="nonce">随机串12位</param>
/// <param name="plainData">明文</param>
/// <param name="associatedData">附加数据(可能null)</param>
/// <returns>只返回加密数据不包含authentication tag</returns>
static string AesGcmEncryptToBase64(string key, string nonce, string plainData, string associatedData)
{
var keyBytes = Encoding.UTF8.GetBytes(key);
var nonceBytes = Encoding.UTF8.GetBytes(nonce);
var associatedBytes = associatedData == null ? null : Encoding.UTF8.GetBytes(associatedData); var plainBytes = Encoding.UTF8.GetBytes(plainData);
var cipherBytes = new byte[plainBytes.Length];
using var cipher = new AesGcm(keyBytes);
//tag size must be is 16
var tag = new byte[16];
cipher.Encrypt(nonceBytes, plainBytes, cipherBytes, tag, associatedBytes); return Convert.ToBase64String(cipherBytes);
} /// <summary>
/// 使用 AesGcm进行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>base64(加密后数据 + authentication tag)</returns>
static string AesGcmEncryptToBase64_WithTag(string key, string nonce, string plainData, string associatedData)
{
var keyBytes = Encoding.UTF8.GetBytes(key);
var nonceBytes = Encoding.UTF8.GetBytes(nonce);
var associatedBytes = associatedData == null ? null : Encoding.UTF8.GetBytes(associatedData); var plainBytes = Encoding.UTF8.GetBytes(plainData);
var cipherBytes = new byte[plainBytes.Length];
//tag size is 16
var tag = new byte[16];
using var cipher = new AesGcm(keyBytes);
cipher.Encrypt(nonceBytes, plainBytes, cipherBytes, tag, associatedBytes); var cipherWithTag = new byte[cipherBytes.Length + tag.Length];
Buffer.BlockCopy(cipherBytes, 0, cipherWithTag, 0, cipherBytes.Length);
Buffer.BlockCopy(tag, 0, cipherWithTag, cipherBytes.Length, tag.Length); return Convert.ToBase64String(cipherWithTag);
}
测试代码
var text = "{'A':123, count:'10', isOk:false, body:{'Text':'select * from table_A where name=@_p1', result:[{'id':1, 'age':23}]}}";
//KEY 必须是两个32位
var key = "1234567890_1234567890_1234567890";
var nonce = "77d0a5ff3937";//Guid.NewGuid().ToString("N").Substring(0, 12);
var associated = "6df132d42d0b4581"; //Guid.NewGuid().ToString("N").Substring(0, 16);
var pythonResult = "PrTO/594j0CYMi2CQF9IFIp7UNkiTtIiIUbmR+jv1c1iO8Ng/HDFHDjL2t0DYo7xo5Vr0O0fUg9hD3bfCoomP+taVaPrW2kJbPTiFXkohXk3T80lQIdWP5lrl21vJvZO3MbmvshyjU+Oxk7pSnjiE5mw/sPXBs4jzS5wtvLUgHvWGaNxzw==";
Console.WriteLine();
var cipherText = AesGcmEncryptToBase64(key, nonce, text, nonce);
Console.WriteLine($"原始密文Base64 :\t{cipherText}");
//Console.WriteLine($"密文tag Base64:\t\t{AesGcmEncryptToBase64(keyBytes, nonceBytes, text, associatedBytes)}");
Console.WriteLine($"Python GCM密文 :\t{pythonResult}");
var cryptText1 = AesGcmEncryptByBouncyCastle(key, nonce, text, associated);
Console.WriteLine($"BouncyCastle密文: \t{cryptText1} ");
var cryptText2 = AesGcmEncryptToBase64_WithTag(key, nonce, text, associated);
Console.WriteLine($"密文+Tag Base64 : \t{cryptText2} ");
Console.WriteLine();
Console.WriteLine();
var t30 = AesGcmDecryptByBouncyCastle(key, nonce, pythonResult, associated);
Console.WriteLine($"BouncyCastle 解密 Python :{t30} \tisOk:{text == t30}");
var t40 = AesGcmDecryptFromBase64(key, nonce, pythonResult, associated);
Console.WriteLine($"AesGcm 解密 Python :{t40} \tisOk:{text == t40}");
Console.WriteLine();
Console.WriteLine();
var t31 = AesGcmDecryptByBouncyCastle(key, nonce, cryptText1, associated);
Console.WriteLine($"BouncyCastle 解密 BouncyCastle:{t31} \tisOk:{text == t31}");
var t41 = AesGcmDecryptFromBase64(key, nonce, cryptText1, associated);
Console.WriteLine($"AesGcm 解密 BouncyCastle:{t41} \tisOk:{text == t41}");
Console.WriteLine();
Console.WriteLine();
var t32 = AesGcmDecryptByBouncyCastle(key, nonce, cryptText2, associated);
Console.WriteLine($"BouncyCastle 解密 密文+Tag :{t32} \tisOk:{text == t32}");
var t42 = AesGcmDecryptFromBase64(key, nonce, cryptText2, associated);
Console.WriteLine($"AesGcm 解密 密文+Tag :{t42} \tisOk:{text == t42}");
转载来源:https://www.cnblogs.com/jzblive/p/14386757.html
C# 中的 AEAD_AES_256_GCM的更多相关文章
- Python开源框架
info:更多Django信息url:https://www.oschina.net/p/djangodetail: Django 是 Python 编程语言驱动的一个开源模型-视图-控制器(MVC) ...
- 项目中使用libsodium扩展
前段时间研究了微信小微商户,地址:https://pay.weixin.qq.com/wiki/doc/api/xiaowei.php?chapter=19_11 其接口操作中需要下载证书针对返回的密 ...
- Java中的微信支付(2):API V3 微信平台证书的获取与刷新
1. 前言 在Java中的微信支付(1):API V3版本签名详解一文中胖哥讲解了微信支付V3版本API的签名,当我方(你自己的服务器)请求微信支付服务器时需要根据我方的API证书对参数进行加签,微信 ...
- mapreduce中一个map多个输入路径
package duogemap; import java.io.IOException; import java.util.ArrayList; import java.util.List; imp ...
- Hadoop 中利用 mapreduce 读写 mysql 数据
Hadoop 中利用 mapreduce 读写 mysql 数据 有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...
- Python中的多进程与多线程(一)
一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...
- .NET Core中的认证管理解析
.NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...
- Angular杂谈系列1-如何在Angular2中使用jQuery及其插件
jQuery,让我们对dom的操作更加便捷.由于其易用性和可扩展性,jQuer也迅速风靡全球,各种插件也是目不暇接. 我相信很多人并不能直接远离jQuery去做前端,因为它太好用了,我们以前做的东西大 ...
- 关于CryptoJS中md5加密以及aes加密的随笔
最近项目中用到了各种加密,其中就包括从没有接触过得aes加密,因此从网上各种查,官方的一种说法: 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学 ...
- In-Memory:在内存中创建临时表和表变量
在Disk-Base数据库中,由于临时表和表变量的数据存储在tempdb中,如果系统频繁地创建和更新临时表和表变量,大量的IO操作集中在tempdb中,tempdb很可能成为系统性能的瓶颈.在SQL ...
随机推荐
- oeasy教您玩转vim - 7 - # 从头插入
另存与保存 回忆上节课内容 上次我们学会了另存为命令 : saveas {file} 还有这个直接保存命令 : w 真的可以把修改存了 下面我们来研究插入命令的细节. 插入命令 首先我们可以查询这个插 ...
- 题解:AT_abc352_d [ABC352D] Permutation Subsequence
虽然比赛没打,但是想来水估值发表思路. 题意 给你一个 \(1\sim n\) 的排列,让你从中找一段长为 \(k\) 的子序列,使得这个子序列中的元素排序后数值连续. 分析 题意转换一下,先用结构体 ...
- golang轻量级的代码复制粘贴检查器 cpd
golang轻量级的代码复制粘贴检查器 cpd 项目地址: https://github.com/dengjiawen8955/copy-paste-detector 快速开始 clone git c ...
- RPC和 HTTP协议
RPC 和HTTP 的区别 服务发现 HTTP,知道服务域名,可以通过 DNS 解析 得到 服务的IP地址,从而进行访问 RPC 需要一个专门的中间服务去保存服务名和IP信息(注册中心,nacos.c ...
- (二)MongoDB的在SpringBoot中的应用
我来填之前MongoDB的坑了,项目中又用到MongoDB的我又想起来了,我这拖延症也是没谁了. 1.在pom.xml中引入依赖 <dependency> <groupId>o ...
- Jax框架 —— 如何在没有GPU和TPU的设备上debug代码 —— 在CPU上使用GPU仿真设置 —— Jax框架在多卡设备上的自动并行特性的仿真体验
Jax计算框架是Google用来取代Tensorflow的新一代计算框架,这个框架使用类似pytorch的技术,但是在pytorch技术之上加入了更加强大的技术,但是这也导致该框架使用起来要比pyto ...
- 始智AI —— https://wisemodel.cn/ —— 试用
清华大学的合资企业推出的服务: 始智AI -- https://wisemodel.cn/ 链接: 始智AI -- https://wisemodel.cn/ 和modelscope比相对简约,毕竟功 ...
- 【转载】 解决运行docker命令要用sudo的问题
将当前登录的用户添加到docker组中,这样以后在访问docker时就不用在sudo了 1. 查看是否创建docker 组 cat /etc/group | grep docker 2.创建docke ...
- 乌克兰学者的学术图谱case5
========================================== 背景: 弗兰采维奇材料问题研究是欧洲最大的材料科研院所,在核电.航空.航天.军工及其他装备制造领域的先进材料研制方 ...
- baselines算法库common/vec_env/subproc_vec_env.py模块分析
模块代码: import multiprocessing as mp import numpy as np from .vec_env import VecEnv, CloudpickleWrappe ...