C# SM2加解密

[删除(380066935@qq.com或微信通知)]

更好的阅读体验请查看原文:https://www.cnblogs.com/YDSLM/archive/2023/06/05/17457526.html

SM2是国家密码管理局于2010年12月17日发布的椭圆曲线公钥密码算法。

产生背景:

        随着密码技术和计算机技术的发展,目前常用的1024位RSA算法面临严重的安全威胁,我们国家密码管理部门经过研究,决定采用SM2椭圆曲线算法替换RSA算法。
        SM2算法和RSA算法都是公钥密码算法,SM2算法是一种更先进安全的算法,在我们国家商用密码体系中被用来替换RSA算法。
 

在.NET中的使用:

        本次介绍使用第三方密码库BouncyCastle实现SM2加解密,使用NuGet搜索BouncyCastle.Cryptography点击安装即可。

1.引入命名空间

using Org.BouncyCastle.Asn1.X9;
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;

 

2.生成SM2密钥对

/// <summary>
/// 生成SM2密钥对,密钥对使用Base64进行编码
/// </summary>
/// <returns>PrivateKey:私钥,PublicKey:公钥</returns>
public static (string PrivateKey,string PublicKey) GenerateKeyPair()
{
      //获取SM2曲线参数
      X9ECParameters curve = ECNamedCurveTable.GetByName("sm2p256v1");
      KeyGenerationParameters parameters = new ECKeyGenerationParameters(new ECDomainParameters(curve), new SecureRandom());

      //创建SM2密钥对生成器
      ECKeyPairGenerator generator = new ECKeyPairGenerator();
      generator.Init(parameters);

      //创建密钥对
      var keyPair = generator.GenerateKeyPair();

      //私钥
      var privateKey = Convert.ToBase64String(((ECPrivateKeyParameters)keyPair.Private).D.ToByteArrayUnsigned());

      //公钥
      var publicKey = Convert.ToBase64String(((ECPublicKeyParameters)keyPair.Public).Q.GetEncoded());

      return (privateKey, publicKey);
}

 

3.使用SM2公钥加密

/// <summary>
/// SM2公钥加密
/// </summary>
/// <param name="strs"></param>
/// <param name="publicKey"></param>
/// <returns></returns>
public static string Encrypt(string strs, string publicKey)
{
      //获取SM2曲线参数
      X9ECParameters curve = ECNamedCurveTable.GetByName("sm2p256v1");

      ECPoint q = curve.Curve.DecodePoint(Convert.FromBase64String(publicKey));
      ECDomainParameters domainParameters = new ECDomainParameters(curve);
      ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters("EC", q, domainParameters);

      //创建SM2加密器
      SM2Engine engine = new SM2Engine();
      engine.Init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));

      //把待加密的字符串转换成字节数组
      byte[] bytes = Encoding.UTF8.GetBytes(strs);

      //执行加密
      byte[] result = engine.ProcessBlock(bytes, 0, bytes.Length);

      //将加密结果转换成Base64字符串,并返回
      return Convert.ToBase64String(result);
}

 

4.SM2私钥解密

/// <summary>
/// SM2私钥解密
/// </summary>
/// <param name="strs"></param>
/// <param name="privateKey"></param>
/// <returns></returns>
public static string Decrypt(string strs, string privateKey)
{
       //获取SM2曲线参数
       X9ECParameters curve = ECNamedCurveTable.GetByName("sm2p256v1");

       ECDomainParameters domainParameters = new ECDomainParameters(curve);
       BigInteger bigInteger = new BigInteger(1, Convert.FromBase64String(privateKey));
       ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(bigInteger, domainParameters);

       //创建SM2解密器
       SM2Engine engine = new SM2Engine();
       engine.Init(false, privateKeyParameters);

       //把待解密的Base64字符串转换成字节数组
       byte[] bytes = Convert.FromBase64String(strs);

       //执行解密
       byte[] result = engine.ProcessBlock(bytes, 0, bytes. Length);

       //将解密结果转换成字符串,并返回
       return Encoding.UTF8.GetString(result);
}

 

总结:

         SM2 密码复杂度高、处理速度快、机器性能消耗更小 被越来越多的程序员熟知和运用,您会在项目中使用SM2加解密吗?