C# SM2 SM3 SM4 使用

效果-SM2

9a83b17a5e427d1acb9403ce7fc9612f.png

公钥:04ca3e272e11b5633681cb0fbbfd8c162be08918ce5b644cd33d49c17be8674caf6c20a11de8b65333924dfe7d42246abb4a4c36b663bef1aafc624a35acf4d2b1
私钥:27e9d8598679a6066f4dfebb2b5d5fe830ce6c6b8b9cf4a4e515e55678ba44a9
原文:测试信息lxw123456!@#$%^&*()abcDEFG
结果:043267543680002a384bdcc8e2db3648f1d5d1a5956ca4798bdfe3ca4a667a620d4df25683e260147ab846a049505ae88ff572f983078f3b1c7d4692c384e6c045292023ff0d69ae3c4f4139b19843a3a5ffa130a1e6758659f4d11a51d32d17a617dda0612319a091a4dcac7e6a67d55f4145c882ca9bbb687641182468a2962d5a0c6bf25ddc

在线校验

地址: https://the-x.cn/cryptography/Sm2.aspx

https://the-x.cn/cryptography/Sm2.aspx

2bc5ba7f3c069afa489cdc9d652e5327.png

效果-SM3

74d1e4f620bb20c2740d6402b54b931e.png

效果-SM4

fbb3c9bc6c6982d7202cdca5975ab958.png

04a9866bbc6e873185c82bef0ed23845.png

项目

49bd79023fd8d88fe461669126b5db23.png

代码

SM2Utils.cs

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.Encoders;
using System;
using System.Text;
 
namespace SMDemo
{
    public class SM2KeyPair
    {
        public string PrivateKey { get; set; } //私钥
        public string PublicKey { get; set; } //公钥
 
    }
    public class SM2Utils
    {
        //国密标准256位曲线参数
        BigInteger SM2_ECC_P = new BigInteger("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16);
        BigInteger SM2_ECC_A = new BigInteger("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", 16);
        BigInteger SM2_ECC_B = new BigInteger("28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", 16);
        BigInteger SM2_ECC_N = new BigInteger("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", 16);
        BigInteger SM2_ECC_H = BigInteger.One;
        BigInteger SM2_ECC_GX = new BigInteger("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16);
        BigInteger SM2_ECC_GY = new BigInteger("BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", 16);
 
        public SM2KeyPair GenerateKey()
        {
            ECCurve curve = new FpCurve(SM2_ECC_P, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H);
            ECPoint g = curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY);
            ECDomainParameters domainParams = new ECDomainParameters(curve, g, SM2_ECC_N);
            ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
            ECKeyGenerationParameters aKeyGenParams = new ECKeyGenerationParameters(domainParams, new SecureRandom());
            keyPairGenerator.Init(aKeyGenParams);
            AsymmetricCipherKeyPair aKp = keyPairGenerator.GenerateKeyPair();
            ECPublicKeyParameters aPub = (ECPublicKeyParameters)aKp.Public;
            ECPrivateKeyParameters aPriv = (ECPrivateKeyParameters)aKp.Private;
 
            BigInteger privateKey = aPriv.D;
            ECPoint publicKey = aPub.Q;
 
            byte[] pubkey = Hex.Encode(publicKey.GetEncoded());
            string temp_pubkey = Encoding.UTF8.GetString(pubkey);
 
            string temp_prikey = Encoding.UTF8.GetString(Hex.Encode(privateKey.ToByteArray()));
 
            return new SM2KeyPair() { PrivateKey = temp_prikey, PublicKey = temp_pubkey };
        }
 
        /// <summary>
        /// 加密函数
        /// </summary>
        /// <param name="publicKeyStr"></param>
        /// <param name="plainText"></param>
        /// <returns></returns>
        public string Encrypt(string publicKeyStr, string plainText)
        {
            byte[] publicKey = Hex.Decode(publicKeyStr);
            byte[] data = Encoding.UTF8.GetBytes(plainText);
 
            if (null == publicKey || publicKey.Length == 0)
            {
                return null;
            }
            if (data == null || data.Length == 0)
            {
                return null;
            }
            byte[] source = new byte[data.Length];
            Array.Copy(data, 0, source, 0, data.Length);
            ECCurve curve = new FpCurve(SM2_ECC_P, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H);
            ECPoint g = curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY);
            ECDomainParameters domainParams = new ECDomainParameters(curve, g, SM2_ECC_N);
            ECPoint userkey = curve.DecodePoint(publicKey);
            ECPublicKeyParameters aPub = new ECPublicKeyParameters(userkey, domainParams);
 
            SM2Engine sm2Engine = new SM2Engine();
            sm2Engine.Init(true, new ParametersWithRandom(aPub));
            byte[] enc = sm2Engine.ProcessBlock(source, 0, source.Length);
            return Encoding.UTF8.GetString(Hex.Encode(enc));
 
        }
 
 
        /// <summary>
        /// 解密函数
        /// </summary>
        /// <param name="privateKey"></param>
        /// <param name="encryptedData"></param>
        /// <returns></returns>
        public string Decrypt(string privateKeyStr, string chiperText)
        {
            byte[] privateKey = Hex.Decode(privateKeyStr);
            byte[] encryptedData = Hex.Decode(chiperText);
 
            if (null == privateKey || privateKey.Length == 0)
            {
                return null;
            }
            if (encryptedData == null || encryptedData.Length == 0)
            {
                return null;
            }
 
            byte[] enc = new byte[encryptedData.Length];
            Array.Copy(encryptedData, 0, enc, 0, encryptedData.Length);
            BigInteger userD = new BigInteger(1, privateKey);
            ECCurve curve = new FpCurve(SM2_ECC_P, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H);
            ECPoint g = curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY);
            ECDomainParameters domainParams = new ECDomainParameters(curve, g, SM2_ECC_N);
            ECPrivateKeyParameters aPriv = new ECPrivateKeyParameters(userD, domainParams);
 
            SM2Engine sm2Engine = new SM2Engine();
            sm2Engine.Init(false, aPriv);
            byte[] dec = sm2Engine.ProcessBlock(enc, 0, enc.Length);
            return Encoding.UTF8.GetString(dec);
        }
    }
}

Sm3Utils.cs

using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Utilities.Encoders;
using System;
using System.Text;
 
namespace SMDemo
{
    public class Sm3Utils
    {
        public static string GetHash(string plainText)
        {
            String resultHexString = "";
            // 将字符串转换成byte数组
            byte[] srcData = Encoding.UTF8.GetBytes(plainText);
            SM3Digest digest = new SM3Digest();
            digest.BlockUpdate(srcData, 0, srcData.Length);
            byte[] hash = new byte[digest.GetDigestSize()];
            digest.DoFinal(hash, 0);
            // 将返回的hash值转换成16进制字符串
            resultHexString = new UTF8Encoding().GetString(Hex.Encode(hash));
            return resultHexString;
        }
    }
}

Sm4Utils.cs

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.Encoders;
using System.Text;
 
namespace SMDemo
{
    public class Sm4Utils
    {
        public static string EncryptEBC(string plaintext, string key)
        {
            var dataBytes = Encoding.UTF8.GetBytes(plaintext);
            var keyBytes = Encoding.UTF8.GetBytes(key);
            KeyParameter keyParam = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
            IBufferedCipher inCipher = CipherUtilities.GetCipher("SM4/ECB/PKCS7Padding");
            inCipher.Init(true, keyParam);
            byte[] cipher = inCipher.DoFinal(dataBytes);
            return Hex.ToHexString(cipher, 0, cipher.Length);
        }
 
        public static string DecryptEBC(string chipherText, string key)
        {
            var dataBytes = Hex.Decode(chipherText);
            var keyBytes = Encoding.UTF8.GetBytes(key);
            KeyParameter keyParam = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
            IBufferedCipher inCipher = CipherUtilities.GetCipher("SM4/ECB/PKCS7Padding");
            inCipher.Init(false, keyParam);
            byte[] plain = inCipher.DoFinal(dataBytes);
            return Encoding.UTF8.GetString(plain);
        }
 
 
        /// <summary>
        /// CBC模式加密
        /// </summary>
        /// <param name="data"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string EncryptCBC(string plaintext, string key)
        {
            var dataBytes = Encoding.UTF8.GetBytes(plaintext);
            var keyBytes = Encoding.UTF8.GetBytes(key);
            KeyParameter keyParam = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
            ParametersWithIV keyParamWithIv = new ParametersWithIV(keyParam, keyBytes);
            IBufferedCipher inCipher = CipherUtilities.GetCipher("SM4/CBC/PKCS7Padding");
            inCipher.Init(true, keyParamWithIv);
            byte[] cipher = inCipher.DoFinal(dataBytes);
            return Hex.ToHexString(cipher, 0, cipher.Length);
        }
 
        /// <summary>
        /// CBC模式解密
        /// </summary>
        /// <param name="data"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string DecryptCBC(string chipherText, string key)
        {
            var dataBytes = Hex.Decode(chipherText);
            var keyBytes = Encoding.UTF8.GetBytes(key);
            KeyParameter keyParam = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
            ParametersWithIV keyParamWithIv = new ParametersWithIV(keyParam, keyBytes);
            IBufferedCipher inCipher = CipherUtilities.GetCipher("SM4/CBC/PKCS7Padding");
            inCipher.Init(false, keyParamWithIv);
            byte[] plain = inCipher.DoFinal(dataBytes);
            return Encoding.UTF8.GetString(plain);
        }
 
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 C# SM2(国密2)示例代码: ```csharp using System; using System.Security.Cryptography; namespace SM2Demo { class Program { static void Main(string[] args) { string plainText = "Hello, SM2!"; // 待加密明文 using (var sm2 = new SM2CryptoServiceProvider()) { var publicKey = sm2.ExportCspBlob(false); // 获取公钥 var privateKey = sm2.ExportCspBlob(true); // 获取私钥 var encryptedData = sm2.Encrypt(Encoding.UTF8.GetBytes(plainText)); // 加密 var decryptedData = sm2.Decrypt(encryptedData); // 解密 Console.WriteLine("Plain text: " + plainText); Console.WriteLine("Encrypted data: " + Convert.ToBase64String(encryptedData)); Console.WriteLine("Decrypted data: " + Encoding.UTF8.GetString(decryptedData)); } } } class SM2CryptoServiceProvider : ECDsa { private readonly CngKey _cngKey; public SM2CryptoServiceProvider() { _cngKey = CngKey.Create(CngAlgorithm.ECDsaP256, null, new CngKeyCreationParameters { ExportPolicy = CngExportPolicies.AllowPlaintextExport }); } public override void ImportParameters(ECParameters parameters) { _cngKey.ImportParameters(parameters); } public override ECParameters ExportParameters(bool includePrivateParameters) { return _cngKey.ExportParameters(includePrivateParameters); } public override byte[] SignData(byte[] data) { throw new NotSupportedException(); } public override bool VerifyData(byte[] data, byte[] signature) { throw new NotSupportedException(); } public override byte[] Encrypt(byte[] plaintext) { using (var provider = new ECDiffieHellmanCng(_cngKey)) { var publicKey = provider.PublicKey.ToByteArray(); var sharedSecret = provider.DeriveKeyMaterial(CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob)); var encryptedData = SM2Utils.Encrypt(plaintext, publicKey, sharedSecret); return encryptedData; } } public override byte[] Decrypt(byte[] ciphertext) { using (var provider = new ECDiffieHellmanCng(_cngKey)) { var publicKey = provider.PublicKey.ToByteArray(); var sharedSecret = provider.DeriveKeyMaterial(CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob)); var decryptedData = SM2Utils.Decrypt(ciphertext, publicKey, sharedSecret); return decryptedData; } } } static class SM2Utils { public static byte[] Encrypt(byte[] plaintext, byte[] publicKey, byte[] sharedSecret) { var cipher = new SM2Cipher(); cipher.Init(true, new SM2Parameters(publicKey)); var encryptedData = cipher.DoFinal(plaintext, sharedSecret); return encryptedData; } public static byte[] Decrypt(byte[] ciphertext, byte[] publicKey, byte[] sharedSecret) { var cipher = new SM2Cipher(); cipher.Init(false, new SM2Parameters(publicKey)); var decryptedData = cipher.DoFinal(ciphertext, sharedSecret); return decryptedData; } } class SM2Cipher { private readonly SM2Engine _engine; public SM2Cipher() { _engine = new SM2Engine(); } public void Init(bool forEncryption, SM2Parameters parameters) { _engine.Init(forEncryption, parameters); } public byte[] DoFinal(byte[] input, byte[] sharedSecret) { var kdf = new SM2KdfBytesGenerator(new Sha256Digest()); kdf.Init(sharedSecret, null); var key = new KeyParameter(kdf.GenerateBytes(32)); var cipher = new PaddedBufferedBlockCipher(_engine); cipher.Init(forEncryption: true, key); var output = new byte[cipher.GetOutputSize(input.Length)]; var outputLength = cipher.ProcessBytes(input, output, outputOffset: 0); outputLength += cipher.DoFinal(output, outputLength); var result = new byte[outputLength]; Array.Copy(output, result, outputLength); return result; } } class SM2KdfBytesGenerator : Kdf1BytesGenerator { private static readonly byte[] _zValue = { 0x00 }; public SM2KdfBytesGenerator(IDigest digest) : base(digest) { } public override int GenerateBytes(byte[] output, int outOff, int length) { var counter = 1; var v = new byte[Digest.GetDigestSize()]; var outputOffset = outOff; var outputRemaining = length; while (outputRemaining > 0) { Digest.BlockUpdate(_zValue, 0, _zValue.Length); Digest.Update((byte)(counter >> 24)); Digest.Update((byte)(counter >> 16)); Digest.Update((byte)(counter >> 8)); Digest.Update((byte)(counter)); Digest.DoFinal(v, 0); var chunkLength = Math.Min(outputRemaining, v.Length); Array.Copy(v, 0, output, outputOffset, chunkLength); outputOffset += chunkLength; outputRemaining -= chunkLength; counter++; } return length; } } class SM2Parameters : ICipherParameters { public byte[] PublicKey { get; } public SM2Parameters(byte[] publicKey) { PublicKey = publicKey; } } } ``` 此示例代码中使用了 Bouncy Castle 库实现 SM2 加密和解密,可以通过 NuGet 安装。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值