bluewelkin 2020-05-10
/// /// 国密SM2算法(ECC算法)加密器 /// 签名部分采用SM3算法进行摘要计算 /// public class Sm2Encryptor { /// /// SM2算法默认用户ID,目前开放平台不会使用非默认用户ID /// public const string DefaultUserId = "1234567812345678"; public string GetAsymmetricType() { return "SM2"; } public (string privatePem, string publicPem) DoKeyPairGenerator() { var SM2_ECC_P = new BigInteger("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16); var SM2_ECC_A = new BigInteger("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", 16); var SM2_ECC_B = new BigInteger("28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", 16); var SM2_ECC_N = new BigInteger("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", 16); var SM2_ECC_H = BigInteger.One; var SM2_ECC_GX = new BigInteger("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16); var SM2_ECC_GY = new BigInteger("BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", 16); var SM2_ECC_Random = new SecureRandom(); ECCurve curve = new FpCurve(SM2_ECC_P, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H); var g = curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY); var domainParams = new ECDomainParameters(curve, g, SM2_ECC_N); var keyPairGenerator = new ECKeyPairGenerator(); var aKeyGenParams = new ECKeyGenerationParameters(domainParams, SM2_ECC_Random); keyPairGenerator.Init(aKeyGenParams); var aKp = keyPairGenerator.GenerateKeyPair(); var aPub = (ECPublicKeyParameters) aKp.Public; var aPriv = (ECPrivateKeyParameters) aKp.Private; var pkinfoPri = PrivateKeyInfoFactory.CreatePrivateKeyInfo(aPriv); var priPem = Convert.ToBase64String(pkinfoPri.GetDerEncoded()); var pkinfoPub = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(aPub); var pubPem = Convert.ToBase64String(pkinfoPub.GetDerEncoded()); return (priPem, pubPem); } public string DoDecrypt(string cipherTextBase64, string charset, string privateKey) { //加载私钥参数 var cipherParams = BuildPrivateKeyParams(privateKey).Parameters; //初始化SM2算法引擎 var sm2Engine = new SM2Engine(); sm2Engine.Init(false, cipherParams); //对输入密文进行解密 var input = Convert.FromBase64String(cipherTextBase64); var output = sm2Engine.ProcessBlock(input, 0, input.Length); //将解密后的明文按指定字符集编码后返回 return Encoding.GetEncoding(charset).GetString(output); } public string DoEncrypt(string plainText, string charset, string publicKey) { //加载公钥参数 var cipherParams = BuildPublicKeyParams(publicKey).Parameters; var parametersWithRandom = new ParametersWithRandom(cipherParams); //初始化SM2算法引擎 var sm2Engine = new SM2Engine(); sm2Engine.Init(true, parametersWithRandom); //对输入明文进行加密 var input = Encoding.GetEncoding(charset).GetBytes(plainText); var output = sm2Engine.ProcessBlock(input, 0, input.Length); //将密文Base64编码后返回 return Convert.ToBase64String(output); } public string DoSign(string content, string charset, string privateKey) { //加载私钥参数 var parametersWithId = BuildPrivateKeyParams(privateKey); //加载签名器 var signer = new SM2Signer(); signer.Init(true, parametersWithId); //向签名器中输入原文 var input = Encoding.GetEncoding(charset).GetBytes(content); signer.BlockUpdate(input, 0, input.Length); //将签名结果转换为Base64 return Convert.ToBase64String(signer.GenerateSignature()); } public bool DoVerify(string content, string charset, string publicKey, string sign) { //加载公钥参数 var parametersWithId = BuildPublicKeyParams(publicKey); //加载签名器 var signer = new SM2Signer(); signer.Init(false, parametersWithId); //向签名器中输入原文 var input = Encoding.GetEncoding(charset).GetBytes(content); signer.BlockUpdate(input, 0, input.Length); //传入指定签名串进行验签并返回结果 return signer.VerifySignature(Convert.FromBase64String(sign)); } private ParametersWithID BuildPrivateKeyParams(string privateKey) { var key = PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey)); var parametersWithId = new ParametersWithID(key, Encoding.UTF8.GetBytes(DefaultUserId)); return parametersWithId; } private static ParametersWithID BuildPublicKeyParams(string publicKey) { var key = PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey)); var parametersWithId = new ParametersWithID(key, Encoding.UTF8.GetBytes(DefaultUserId)); return parametersWithId; } } //推荐参数http://www.oscca.gov.cn/sca/xxgk/2010-12/17/content_1002386.shtml //参考:https://github.com/alipay/alipay-sdk-net-all //参考:https://github.com/Arthurvdmerwe/AS2805.6.5.3/blob/6ee870947c0504da427734604aa79503d8ee3607/Crypto/test/src/crypto/test/SM2EngineTest.cs