網上找了一圈,發現.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)); } } }