C# SM2(国密2)示例代码
时间: 2023-08-02 10:45:55 浏览: 509
以下是一个简单的 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 安装。
阅读全文
相关推荐
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![application/x-zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![-](https://img-home.csdnimg.cn/images/20241231044955.png)
![-](https://img-home.csdnimg.cn/images/20241231044955.png)
![-](https://img-home.csdnimg.cn/images/20241231044955.png)
![-](https://img-home.csdnimg.cn/images/20241231044955.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)