using System; using System.Text; using System.Threading.Tasks; using Org.BouncyCastle.Asn1.GM; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Prng; using Org.BouncyCastle.Security; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Pkcs; using StellaOps.Cryptography; using StellaOps.Cryptography.Plugin.SmSoft; using Xunit; namespace StellaOps.Cryptography.Tests; public class SmSoftCryptoProviderTests : IDisposable { private readonly string? _originalGate; public SmSoftCryptoProviderTests() { _originalGate = Environment.GetEnvironmentVariable("SM_SOFT_ALLOWED"); Environment.SetEnvironmentVariable("SM_SOFT_ALLOWED", "1"); } [Fact] public async Task SignAndVerify_Sm2_Works() { var provider = new SmSoftCryptoProvider(); var key = GenerateSm2Key(); provider.UpsertSigningKey(key); var signer = provider.GetSigner(SignatureAlgorithms.Sm2, key.Reference); var payload = Encoding.UTF8.GetBytes("sm2-payload"); var signature = await signer.SignAsync(payload); Assert.True(await signer.VerifyAsync(payload, signature)); var jwk = signer.ExportPublicJsonWebKey(); Assert.Equal(SignatureAlgorithms.Sm2, jwk.Alg); Assert.Equal("SM2", jwk.Crv); Assert.Equal(key.Reference.KeyId, jwk.Kid); Assert.False(string.IsNullOrEmpty(jwk.X)); Assert.False(string.IsNullOrEmpty(jwk.Y)); } [Fact] public void Hash_Sm3_Works() { var provider = new SmSoftCryptoProvider(); var hasher = provider.GetHasher(HashAlgorithms.Sm3); var digest = hasher.ComputeHashHex(Encoding.UTF8.GetBytes("abc")); // Known SM3("abc") = 66c7f0f462eeedd9d1f2d46bdc10e4e2 4167c4875cf2f7a2 297da02b8f4ba8e0 Assert.Equal("66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", digest); } private static CryptoSigningKey GenerateSm2Key() { var generator = new ECKeyPairGenerator("EC"); var curve = GMNamedCurves.GetByName("SM2P256V1"); var domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H, curve.GetSeed()); generator.Init(new ECKeyGenerationParameters(domain, new SecureRandom(new CryptoApiRandomGenerator()))); var pair = generator.GenerateKeyPair(); var privateDer = PrivateKeyInfoFactory.CreatePrivateKeyInfo(pair.Private).ToAsn1Object().GetDerEncoded(); var keyRef = new CryptoKeyReference("sm-soft-test"); return new CryptoSigningKey(keyRef, SignatureAlgorithms.Sm2, privateDer, DateTimeOffset.UtcNow); } public void Dispose() { Environment.SetEnvironmentVariable("SM_SOFT_ALLOWED", _originalGate); } }