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

一种C# 的SM4 的 加解密的实现,一般用于医疗或者支付

一种C# 的SM4 的 加解密的实现

一般用于医疗或者支付

加密

 string cipherText = SM4Helper.Encrypt_test(data, key);

        public static string Encrypt_test(string plainText, string key)
        {

            byte[] keyBytes = Encoding.ASCII.GetBytes(key);
            byte[] inputBytes = Encoding.UTF8.GetBytes(plainText);

            // 初始化SM4引擎
            var engine = new SM4Engine();
            var cipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding());
            cipher.Init(true, new KeyParameter(keyBytes));

            // 执行加密
            byte[] output = new byte[cipher.GetOutputSize(inputBytes.Length)];
            int len = cipher.ProcessBytes(inputBytes, 0, inputBytes.Length, output, 0);
            cipher.DoFinal(output, len);

            // 转换为大写十六进制字符串
            return BitConverter.ToString(output).Replace("-", "").ToUpper();
        }

解密

string decryptedText = SM4Helper.Decrypt_test(cipherText, key);

  public static string Decrypt_test(string plainText, string key)
        {

            byte[] keyBytes = Encoding.ASCII.GetBytes(key);
            byte[] inputBytes = FromHexString(plainText);

            // 初始化SM4引擎
            var engine = new SM4Engine();  
            var cipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding());
            cipher.Init(false, new KeyParameter(keyBytes)); // false表示解密模式

            // 执行解密
            byte[] output = new byte[cipher.GetOutputSize(inputBytes.Length)];
            int len = cipher.ProcessBytes(inputBytes, 0, inputBytes.Length, output, 0);
            len += cipher.DoFinal(output, len);

            // 移除可能的填充字节
            byte[] result = new byte[len];
            Array.Copy(output, result, len);

            return Encoding.UTF8.GetString(result);
        }

SM4Helper 的全部代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Globalization;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;namespace OneClikPay
{public class SM4Helper{/// <summary>/// SM4加密(ECB模式,PKCS7填充)/// </summary>public static string Encrypt(string plainText, string hexKey){byte[] keyBytes = FromHexString(hexKey); // 使用严格兼容的十六进制转换byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);var cipher = CreateCipher(true, keyBytes);byte[] encrypted = cipher.DoFinal(plainBytes);return BytesToHex(encrypted);}/// <summary>/// SM4解密(ECB模式,PKCS7填充)/// </summary>public static string Decrypt(string hexCipherText, string hexKey){byte[] keyBytes = FromHexString(hexKey);byte[] cipherBytes = FromHexString(hexCipherText);var cipher = CreateCipher(false, keyBytes);byte[] decrypted = cipher.DoFinal(cipherBytes);return Encoding.UTF8.GetString(decrypted);}#region 核心加密模块private static BufferedBlockCipher CreateCipher(bool forEncryption, byte[] key){// 严格校验密钥长度if (key.Length != 16)throw new ArgumentException("密钥必须为128位(16字节)");IBlockCipher engine = new SM4Engine();var cipher = new PaddedBufferedBlockCipher(new EcbBlockCipher(engine), new Pkcs7Padding());cipher.Init(forEncryption, new KeyParameter(key));return cipher;}#endregion#region 完全兼容Java的十六进制转换(ByteUtils.fromHexString等效实现)public static byte[] FromHexString(string hex){if (hex == null)throw new ArgumentNullException(nameof(hex));hex = hex.Trim().Replace(" ", "").Replace("\n", "").Replace("\t", "");if (hex.Length % 2 != 0)throw new FormatException("十六进制字符串长度必须为偶数");byte[] bytes = new byte[hex.Length / 2];for (int i = 0; i < bytes.Length; i++){string hexByte = hex.Substring(i * 2, 2);if (!IsHexChar(hexByte[0]) || !IsHexChar(hexByte[1]))throw new FormatException($"非法十六进制字符: {hexByte}");bytes[i] = byte.Parse(hexByte, NumberStyles.HexNumber, CultureInfo.InvariantCulture);}return bytes;}private static bool IsHexChar(char c){return (c >= '0' && c <= '9') ||(c >= 'a' && c <= 'f') ||(c >= 'A' && c <= 'F');}private static string BytesToHex(byte[] bytes){StringBuilder hex = new StringBuilder(bytes.Length * 2);foreach (byte b in bytes){hex.AppendFormat("{0:X2}", b); // 强制大写,与Java的Hex.toHexString()一致}return hex.ToString();}#endregionpublic static string Encrypt_test(string plainText, string key){byte[] keyBytes = Encoding.ASCII.GetBytes(key);byte[] inputBytes = Encoding.UTF8.GetBytes(plainText);// 初始化SM4引擎var engine = new SM4Engine();var cipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding());cipher.Init(true, new KeyParameter(keyBytes));// 执行加密byte[] output = new byte[cipher.GetOutputSize(inputBytes.Length)];int len = cipher.ProcessBytes(inputBytes, 0, inputBytes.Length, output, 0);cipher.DoFinal(output, len);// 转换为大写十六进制字符串return BitConverter.ToString(output).Replace("-", "").ToUpper();}public static string Decrypt_test(string plainText, string key){byte[] keyBytes = Encoding.ASCII.GetBytes(key);byte[] inputBytes = FromHexString(plainText);// 初始化SM4引擎var engine = new SM4Engine();  var cipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding());cipher.Init(false, new KeyParameter(keyBytes)); // false表示解密模式// 执行解密byte[] output = new byte[cipher.GetOutputSize(inputBytes.Length)];int len = cipher.ProcessBytes(inputBytes, 0, inputBytes.Length, output, 0);len += cipher.DoFinal(output, len);// 移除可能的填充字节byte[] result = new byte[len];Array.Copy(output, result, len);return Encoding.UTF8.GetString(result);}}
}

http://www.xdnf.cn/news/9239.html

相关文章:

  • 如何在WordPress网站中添加相册/画廊
  • 【分治】计算右侧小于当前元素的个数
  • Java集合框架详解:List、Set、Map及其实现类
  • 电子信息科学与技术专业生涯规划书-嵌入式方向(大一下)
  • 《计算机组成原理》第 3 章 - 系统总线
  • 微服务难题?Nacos服务发现来救场
  • 向量数据库对比和选择:Pinecone、Chroma、FAISS、Milvus、Weaviate
  • sqli-第三十二关——bypass addslashes
  • 使用redis代替session的登录校验
  • 企业微信内部网页开发流程笔记
  • [Java恶补day8] 3. 无重复字符的最长子串
  • 一起学数据结构和算法(三)| 字符串(线性结构)
  • 零基础远程连接课题组Linux服务器,安装anaconda,配置python环境(换源),在服务器上运行python代码【1/3 适合小白,步骤详细!!!】
  • 在 Vue 2中使用 dhtmlxGantt 7.1.13组件,并解决使用时遇到的问题汇总.“dhtmlx-gantt“: “^7.1.13“,
  • Linux中Java开发、部署和运维常用命令
  • uni-app学习笔记十五-vue3页面生命周期(一)
  • unity实现wasd键控制汽车漫游
  • 国产三维CAD皇冠CAD(CrownCAD)建模教程:汽车电池
  • 洛谷 P3372 【模板】线段树 1
  • android 输入系统
  • 不同电脑同一个网络ip地址一样吗
  • 打卡第38天
  • 数据透视:水安 B 证如何影响水利企业的生存指数?
  • Java爬虫,获取未来40天预测气象并写入Excel
  • 制作一款打飞机游戏58:子弹模式组合
  • 低空经济数据湖架构设计方案
  • 在springboot,禁止查询数据库种的某字段
  • 【linux篇】动静态库和自动化构建的“神之一手”:make、Makefile
  • AtCoder 第407场初级竞赛 A~E题解
  • java helloWord java程序运行机制 用idea创建一个java项目 标识符 关键字 数据类型 字节