网上找了一圈,发现.NET core关于本次实名认证
https://wlc.nppa.gov.cn/2021/02/25/16e2520acd9f4404897ed1a5b8fd1240.pdf
相关博客没有,根据node.js的代码用.NET core实现,然后分享给大家
aes具体的算法就不赘述了,详情可以看
https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.aesgcm?view=net-5.0
提几个比较关键的点
1、nonce是固定12位,被加在密文的前面
2、tag是16位,被加在密文的后面
3、key是32位的16进制的字符串,使用时要根据对应函数转化成byte[]
4、测试的密文总长度是136位,经过base64解码之后是102位,原文的长度是74位,加上nonce(12位)与tag(16位)正好是102位
下面是测试代码,环境是.NET core 3.1
using System; using System.Security.Cryptography; using System.Text; namespace aesgcmtest { class Program { //16进制string转byte[] public static byte[] StrToHexByte(string hexString) { hexString = hexString.Replace(" ", "", StringComparison.CurrentCulture); 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 string Decrypt(string hexStrKey, string base64Cliper) { //1.将16进制的密钥转化为byte数组 var key = StrToHexByte(hexStrKey); //2.将base64格式的密文转化为byte数组136位->102位 var cliper = Convert.FromBase64String(base64Cliper); var nonce = new byte[12]; var tag = new byte[16]; var clipertext = new byte[cliper.Length - 28]; var plaintext = new byte[cliper.Length - 28]; //3.密文的前12位为nonce Array.ConstrainedCopy(cliper, 0, nonce, 0, 12); //4.密文的后16位为tag Array.ConstrainedCopy(cliper, cliper.Length - 16, tag, 0, 16); //5.密文长度与加密原文长度一致 Array.ConstrainedCopy(cliper, 12, clipertext, 0, cliper.Length - 28); //6.解密 using var aesGcm = new AesGcm(key); aesGcm.Decrypt(nonce, clipertext, tag, plaintext); //7.将byte数组转化为string并返回 return Encoding.Default.GetString(plaintext); } public static string Encrypt(string hexStrKey, string plain) { //1.将16进制的密钥转化为byte数组 var key = StrToHexByte(hexStrKey); //2.将string格式的原文转化为byte数组 var plaintext = Encoding.Default.GetBytes(plain); //2.1密文与原文等长 var ciphertext = new byte[plaintext.Length]; //3.随机数,给nonce赋值随机数 Random rand = new Random(); var nonce = new byte[12]; var tag = new byte[16]; rand.NextBytes(nonce); //4.加密 using var aesGcm = new AesGcm(key); aesGcm.Encrypt(nonce, plaintext, ciphertext, tag); //5.将nonce(12位)拼在密文前,将tag(16位拼在密文后) var cipher = new byte[ciphertext.Length + 28]; Array.ConstrainedCopy(nonce, 0, cipher, 0, 12); Array.ConstrainedCopy(ciphertext, 0, cipher, 12, ciphertext.Length); Array.ConstrainedCopy(tag, 0, cipher, 12 + ciphertext.Length, 16); return Convert.ToBase64String(cipher); } static void Main() { var hexStrKey = @"2836e95fcd10e04b0069bb1ee659955b"; var base64Cliper = @"CqT/33f3jyoiYqT8MtxEFk3x2rlfhmgzhxpHqWosSj4d3hq2EbrtVyx2aLj565ZQNTcPrcDipnvpq/D/vQDaLKW70O83Q42zvR0//OfnYLcIjTPMnqa+SOhsjQrSdu66ySSORCAo"; var plaintext = Decrypt(hexStrKey, base64Cliper); Console.WriteLine("解密成功,测试原文:" + plaintext); plaintext = ".NET 666"; var ciphertext = Encrypt(hexStrKey, plaintext); Console.WriteLine("加密成功,密文:" + ciphertext); Console.WriteLine("解密成功,原文:" + Decrypt(hexStrKey, ciphertext)); } } }