一种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
    {
        /// 
        /// SM4加密(ECB模式,PKCS7填充)
        /// 
        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);
        }

        /// 
        /// SM4解密(ECB模式,PKCS7填充)
        /// 
        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();
        }
        #endregion
        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();
        }
        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);
        }
    }
}

你可能感兴趣的:(Microsoft,Visual,Studio开发技术分享,医疗行业开发技术分享,c#,开发语言,健康医疗)