编辑
2025-09-27
C#
00

目录

特点
应用场景
代码示例
第三方库BouncyCastle
代码说明
小结

SM2是由中国国家密码管理局制定的公钥密码算法,属于国家密码标准之一。SM2算法基于椭圆曲线密码学,兼具安全性和高效性,被广泛应用在金融、电子政务和电子商务等领域。

特点

  1. 安全性:SM2基于椭圆曲线密码学,提供高强度的安全保障。
  2. 高效性:在相同的安全强度下,SM2比RSA和DSA更加高效,计算复杂度较低。
  3. 国家标准:SM2是中国国家密码标准GB/T 32918,具有国家认可的权威性。

应用场景

  1. 数字签名:用于身份验证和不可否认性。
  2. 数据加密:用于保护敏感信息的传输与存储。
  3. 密钥交换:用于安全的密钥分发和交换过程。

代码示例

第三方库BouncyCastle

image.png

C#
using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Asn1.GM; using System.Security.Cryptography.X509Certificates; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Math; namespace AppSm2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void btnCreateKey_Click(object sender, EventArgs e) { // 1. 生成SM2密钥对 var keyPair = GenerateSM2KeyPair(); var publicKey = (ECPublicKeyParameters)keyPair.Public; var privateKey = (ECPrivateKeyParameters)keyPair.Private; File.WriteAllText("./public.dat", Convert.ToBase64String(publicKey.Q.GetEncoded())); File.WriteAllText("./private.dat", Convert.ToBase64String(privateKey.D.ToByteArrayUnsigned())); } /// <summary> /// 生成公私钥 /// </summary> /// <returns></returns> private AsymmetricCipherKeyPair GenerateSM2KeyPair() { // 使用国标曲线参数 "Wapi" 被GMNamedCurves定义 (SM2标准曲线) X9ECParameters sm2Params = GMNamedCurves.GetByName("sm2p256v1"); var ecParams = new ECDomainParameters(sm2Params.Curve, sm2Params.G, sm2Params.N, sm2Params.H); var keyGenerationParameters = new ECKeyGenerationParameters(ecParams, new SecureRandom()); var keyPairGenerator = new ECKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); return keyPairGenerator.GenerateKeyPair(); } private void btnEncrypt_Click(object sender, EventArgs e) { // 将Base64格式公钥转换回ECPublicKeyParameters var restoredPublicKey = RestorePublicKeyFromBase64(File.ReadAllText("./public.dat")); byte[] cipherText = Encrypt(txt1.Text, restoredPublicKey); txt2.Text = Convert.ToBase64String(cipherText); } /// <summary> /// 还原公钥 /// </summary> /// <param name="base64PublicKey"></param> /// <returns></returns> private ECPublicKeyParameters RestorePublicKeyFromBase64(string base64PublicKey) { // 将Base64格式的公钥字符串转换为字节数组 byte[] publicKeyBytes = Convert.FromBase64String(base64PublicKey); // 获取SM2曲线参数,这里使用sm2p256v1曲线 X9ECParameters sm2Params = GMNamedCurves.GetByName("sm2p256v1"); // 创建ECDomainParameters对象,包含曲线的一些基本参数,如曲线、生成元G、阶N和系数H var ecParams = new ECDomainParameters(sm2Params.Curve, sm2Params.G, sm2Params.N, sm2Params.H); // 使用曲线参数解码公钥字节数组,将其转换为ECPoint var q = sm2Params.Curve.DecodePoint(publicKeyBytes); // 根据解码后的ECPoint和ECDomainParameters创建ECPublicKeyParameters对象 return new ECPublicKeyParameters(q, ecParams); } /// <summary> /// 加密 /// </summary> /// <param name="plainText"></param> /// <param name="publicKey"></param> /// <returns></returns> private byte[] Encrypt(string plainText, ECPublicKeyParameters publicKey) { var sm2Engine = new SM2Engine(); sm2Engine.Init(true, new ParametersWithRandom(publicKey, new SecureRandom())); byte[] plainBytes = System.Text.Encoding.UTF8.GetBytes(plainText); return sm2Engine.ProcessBlock(plainBytes, 0, plainBytes.Length); } private void btnDecrypt_Click(object sender, EventArgs e) { var restoredPrivateKey = RestorePrivateKeyFromBase64(File.ReadAllText("./private.dat")); string decryptedText = Decrypt(txt2.Text, restoredPrivateKey); txt3.Text = decryptedText; } /// <summary> /// 解密 /// </summary> /// <param name="base64CipherText"></param> /// <param name="privateKey"></param> /// <returns></returns> private static string Decrypt(string base64CipherText, ECPrivateKeyParameters privateKey) { var sm2Engine = new SM2Engine(); sm2Engine.Init(false, privateKey); byte[] cipherBytes = Convert.FromBase64String(base64CipherText); byte[] decryptedBytes = sm2Engine.ProcessBlock(cipherBytes, 0, cipherBytes.Length); return System.Text.Encoding.UTF8.GetString(decryptedBytes); } /// <summary> /// 还私公钥 /// </summary> /// <param name="base64PrivateKey"></param> /// <returns></returns> private ECPrivateKeyParameters RestorePrivateKeyFromBase64(string base64PrivateKey) { // 将Base64格式的私钥字符串转换为字节数组 byte[] privateKeyBytes = Convert.FromBase64String(base64PrivateKey); // 使用BigInteger构造函数将字节数组转换为无符号大整数,这将表示我们的私钥 BigInteger d = new BigInteger(1, privateKeyBytes); // 获取SM2曲线参数,这里使用sm2p256v1曲线 X9ECParameters sm2Params = GMNamedCurves.GetByName("sm2p256v1"); // 创建ECDomainParameters对象,包含曲线的一些基本参数,如曲线、生成元G、阶N和系数H var ecParams = new ECDomainParameters(sm2Params.Curve, sm2Params.G, sm2Params.N, sm2Params.H); // 根据无符号大整数和ECDomainParameters创建ECPrivateKeyParameters对象,表示私钥 return new ECPrivateKeyParameters(d, ecParams); } } }

image.png

代码说明

  1. 生成密钥对:使用GenerateSM2KeyPair方法生成SM2密钥对。
  2. 加密:用公钥加密明文,返回密文。
  3. 解密:用私钥解密密文,返回明文。

小结

本文介绍了SM2算法的基本特点、应用场景,并提供了一个完整的C#示例代码。通过BouncyCastle库,开发者可以方便地在C#应用程序中实现SM2加密和解密操作。

SM2作为中国国家密码标准,在确保信息安全传输方面起到了至关重要的作用。在未来的应用中,SM2有望在更多领域中发挥更大的作用。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!