整理sm2國密算法


    /// 
    ///     國密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



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM