当前位置: 首页 > news >正文

国密起步7:BouncyCastle使用SM4自定义格式加解密C#版

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。

github源码指引的指引-CSDN博客


        本文是国密起步6:GmSSL3使用SM4自定义格式加解密C++版-CSDN博客的对应C#版。

        GmSSL没有C#接口,所以C#上要用别的库,比如BouncyCastle这个著名加解密库。nuget上的名字是BouncyCastle.Cryptography。

一、源码

        因为是跟C++版是对照关系,直接上源码了:

	static public string gm4DecryptMessage(string text, string userkey){try{byte[] encryptdata = Convert.FromBase64String(text);//格式为版本1字节、IV16字节、加密后的数据(第一个块是明文长度,仅用8字节,其余未用)byte[] key = new byte[16];//密钥var bytesUserKey = Encoding.UTF8.GetBytes(userkey);for (int i = 0; i < 16; ++i){if (i < userkey.Length) key[i] = bytesUserKey[i];else key[i] = 0;}KeyParameter Key = ParameterUtilities.CreateKeyParameter("SM4", key);ParametersWithIV keyParamWithIv = new ParametersWithIV(Key, encryptdata.Skip(1).Take(16).ToArray());IBufferedCipher inCipher = CipherUtilities.GetCipher("SM4/CBC/NoPadding");inCipher.Init(false, keyParamWithIv);byte[] full_plaindata = inCipher.ProcessBytes(encryptdata.Skip(17).ToArray());int nPlainLength = (int)BitConverter.ToInt64(full_plaindata.Take(8).ToArray());text = Encoding.UTF8.GetString(full_plaindata.Skip(16).Take(nPlainLength).ToArray());}catch (Exception ex){text = ex.ToString();}return text;}static public string gm4EncryptMessage(string text, string userkey){try{//格式为版本1字节、IV16字节、加密后的数据(第一个块是明文长度,仅用8字节,其余未用)byte[] key = new byte[16];//密钥var bytesUserKey = Encoding.UTF8.GetBytes(userkey);for (int i = 0; i < 16; ++i){if (i < userkey.Length) key[i] = bytesUserKey[i];else key[i] = 0;}byte[] IV = new byte[16];Random rand = new Random();for (int i = 0; i < 16; ++i) IV[i] = (byte)rand.Next(0, 255);KeyParameter Key = ParameterUtilities.CreateKeyParameter("SM4", key);ParametersWithIV keyParamWithIv = new ParametersWithIV(Key, IV);IBufferedCipher inCipher = CipherUtilities.GetCipher("SM4/CBC/NoPadding");inCipher.Init(true, keyParamWithIv);int plainBufLen;//明文缓冲区长度,第一个块是明文长度,其后是原始数据,按照16字节补齐if (0 == text.Length % 16) plainBufLen = 16 + text.Length;else plainBufLen = 16 + (text.Length / 16 + 1) * 16;byte[] plainBuf = new byte[plainBufLen];BitConverter.GetBytes((long)text.Length).CopyTo(plainBuf, 0);//必须是8位整数Encoding.UTF8.GetBytes(text).CopyTo(plainBuf, 16);byte[] tmp = new byte[1 + 16 + plainBufLen];//输出缓冲区tmp[0] = 1;IV.CopyTo(tmp, 1);byte[] cipher = inCipher.ProcessBytes(plainBuf);cipher.CopyTo(tmp, 17);text = "G" + Convert.ToBase64String(tmp);}catch (Exception ex){text = ex.ToString();}return text;}

         加密后的数据转为base64编码并增加一个“G”开头。实际使用的格式是这样的:

  • 明文,json格式,总是以‘{’开头
  • 压缩,C+base64
  • AES,E+base64
  • 国密,G+base64

         所以不会有冲突。


(这里是文档结束)        

http://www.lryc.cn/news/440306.html

相关文章:

  • Qt优秀开源项目之二十三:QSimpleUpdater
  • 使用 Nmap 进行 SSL/TLS 加密套件枚举
  • 探索 Python 的火焰:Fire 库的神秘力量
  • 【Day14-单例设计模式动态代理】
  • 代码随想录训练营Day7 | 454.四数相加II | 383. 赎金信 | 15. 三数之和 | 18. 四数之和
  • C++和OpenGL实现3D游戏编程【目录】
  • 03-Mac系统PyCharm主题设置
  • Java并发的四大定律
  • java项目之基于springboot的贸易行业crm系统(源码+文档)
  • General OCR Theory: Towards OCR-2.0 via a Unified End-to-end Model
  • 二十种编程语言庆祝中秋节
  • 202409012在飞凌的OK3588-C的核心板上使用Rockchip原厂的Buildroot点MIPI屏【背光篇】
  • DMDRS搭建
  • 【油猴脚本】00006 案例 Tampermonkey油猴脚本自定义表格列名称,自定义表格表头,自定义表格的thead里的td
  • JS - 获取剪切板内容 Clipboard API
  • Qt自动打开文件夹并高亮文件
  • 神经网络-MNIST数据集训练
  • 数据结构二
  • Python|基于Kimi大模型,删除已上传的“指定文档”或“全部文档”(6)
  • CenterPoint-KITTI:环境配置、模型训练、效果展示;KITTI 3D 目标检测数据集下载
  • 【Android】ViewPager
  • [go] 命令模式
  • 代码随想录冲冲冲 Day48 单调栈Part2
  • 企业内训|Nvidia智算中心深度技术研修-某智算厂商研发中心
  • 《算法笔记》例题解析 第3章入门模拟--3图形输出(9题)2021-03-03
  • 合宙Air201模组LuatOS:PWRKEY控制,一键解决解决关机难问题
  • Kafka 命令详解及使用示例
  • 重生归来之挖掘stm32底层知识(1)——寄存器
  • Qt构建JSON及解析JSON
  • 合宙Air201模组LuatOS扩展功能:温湿度传感器篇!