ソースを参照

😁密码经过国密SM2加密传输(前端加密后台解密)

zuohuaijun 2 年 前
コミット
ccca4c282a

+ 2 - 2
Admin.NET/Admin.NET.Application/Configuration/App.json

@@ -43,7 +43,7 @@
     "PasswordStrengthValidation": "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[~@#$%\\*-\\+=:,\\\\?\\[\\]\\{}]).{6,16}$", // 密码强度验证正则表达式,必须须包含大小写字母、数字和特殊字符的组合,长度在6-16之间
     "PasswordStrengthValidationMsg": "密码必须包含大小写字母、数字和特殊字符的组合,长度在6-16之间", // 密码强度验证消息提示
     "CryptoType": "SM2", // 密码加密算法:MD5、SM2、SM4
-    "PublicKey": "04F6E0C3345AE42B51E06BF50B98834988D54EBC7460FE135A48171BC0629EAE205EEDE253A530608178A98F1E19BB737302813BA39ED3FA3C51639D7A20C7391A", // 公钥
-    "PrivateKey": "3690655E33D5EA3D9A4AE1A1ADD766FDEA045CDEAA43A9206FB8C430CEFE0D94" // 私钥
+    "PublicKey": "0484c7466d950e120e5ece5dd85d0c90eaa85081a3a2bd7c57ae6dc822efccbd66620c67b0103fc8dd280e36c3b282977b722aaec3c56518edcebafb72c5a05312", // 公钥
+    "PrivateKey": "8edb615b1d48b8be188fc0f18ec08a41df50ea731fa28bf409e6552809e3a111" // 私钥
   }
 }

+ 3 - 0
Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs

@@ -80,6 +80,9 @@ public class SysAuthService : IDynamicApiController, ITransient
         if (tenant != null && tenant.Status == StatusEnum.Disable)
             throw Oops.Oh(ErrorCodeEnum.Z1003);
 
+        // 国密SM2解密(前端密码传输SM2加密后的)
+        input.Password = CryptogramUtil.SM2Decrypt(input.Password);
+
         // 密码是否正确
         if (CryptogramUtil.CryptoType == CryptogramEnum.MD5.ToString())
         {

+ 6 - 13
Admin.NET/Admin.NET.Core/Util/CryptogramUtil.cs

@@ -7,8 +7,6 @@
 // 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
 // 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
 
-using Org.BouncyCastle.Utilities.Encoders;
-
 namespace Admin.NET.Core;
 
 public class CryptogramUtil
@@ -67,8 +65,7 @@ public class CryptogramUtil
     /// <returns></returns>
     public static string SM2Encrypt(string plainText)
     {
-        byte[] sourceData = Encoding.Default.GetBytes(plainText);
-        return SM2Util.Encrypt(Hex.Decode(PublicKey), sourceData);
+        return GMUtil.SM2Encrypt(PublicKey, plainText);
     }
 
     /// <summary>
@@ -78,7 +75,7 @@ public class CryptogramUtil
     /// <returns></returns>
     public static string SM2Decrypt(string cipherText)
     {
-        return Encoding.Default.GetString(SM2Util.Decrypt(Hex.Decode(PrivateKey), Hex.Decode(cipherText)));
+        return GMUtil.SM2Decrypt(PrivateKey, cipherText);
     }
 
     /// <summary>
@@ -88,8 +85,7 @@ public class CryptogramUtil
     /// <returns></returns>
     public static string SM4EncryptECB(string plainText)
     {
-        var sm4 = new SM4Util();
-        return sm4.Encrypt_ECB(plainText);
+        return GMUtil.SM4EncryptECB(plainText);
     }
 
     /// <summary>
@@ -99,8 +95,7 @@ public class CryptogramUtil
     /// <returns></returns>
     public static string SM4DecryptECB(string cipherText)
     {
-        var sm4 = new SM4Util();
-        return sm4.Decrypt_ECB(cipherText);
+        return GMUtil.SM4DecryptECB(cipherText);
     }
 
     /// <summary>
@@ -110,8 +105,7 @@ public class CryptogramUtil
     /// <returns></returns>
     public static string SM4EncryptCBC(string plainText)
     {
-        var sm4 = new SM4Util();
-        return sm4.Encrypt_CBC(plainText);
+        return GMUtil.SM4EncryptCBC(plainText);
     }
 
     /// <summary>
@@ -121,7 +115,6 @@ public class CryptogramUtil
     /// <returns></returns>
     public static string SM4DecryptCBC(string cipherText)
     {
-        var sm4 = new SM4Util();
-        return sm4.Decrypt_CBC(cipherText);
+        return GMUtil.SM4DecryptCBC(cipherText);
     }
 }

+ 472 - 0
Admin.NET/Admin.NET.Core/Util/GM/GM.cs

@@ -0,0 +1,472 @@
+// 麻省理工学院许可证
+//
+// 版权所有 (c) 2021-2023 zuohuaijun,大名科技(天津)有限公司  联系电话/微信:18020030720  QQ:515096995
+//
+// 特此免费授予获得本软件的任何人以处理本软件的权利,但须遵守以下条件:在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
+//
+// 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
+// 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.GM;
+using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Digests;
+using Org.BouncyCastle.Crypto.Engines;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.X509;
+
+namespace Admin.NET.Core;
+
+/**
+ *
+ * 用BC的注意点:
+ * 这个版本的BC对SM3withSM2的结果为asn1格式的r和s,如果需要直接拼接的r||s需要自己转换。下面rsAsn1ToPlainByteArray、rsPlainByteArrayToAsn1就在干这事。
+ * 这个版本的BC对SM2的结果为C1||C2||C3,据说为旧标准,新标准为C1||C3||C2,用新标准的需要自己转换。下面(被注释掉的)changeC1C2C3ToC1C3C2、changeC1C3C2ToC1C2C3就在干这事。java版的高版本有加上C1C3C2,csharp版没准以后也会加,但目前还没有,java版的目前可以初始化时“ SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);”。
+ *
+ */
+
+public class GM
+{
+    private static X9ECParameters x9ECParameters = GMNamedCurves.GetByName("sm2p256v1");
+    private static ECDomainParameters ecDomainParameters = new(x9ECParameters.Curve, x9ECParameters.G, x9ECParameters.N);
+
+    /**
+     *
+     * @param msg
+     * @param userId
+     * @param privateKey
+     * @return r||s,直接拼接byte数组的rs
+     */
+
+    public static byte[] SignSm3WithSm2(byte[] msg, byte[] userId, AsymmetricKeyParameter privateKey)
+    {
+        return RsAsn1ToPlainByteArray(SignSm3WithSm2Asn1Rs(msg, userId, privateKey));
+    }
+
+    /**
+      * @param msg
+      * @param userId
+      * @param privateKey
+      * @return rs in <b>asn1 format</b>
+      */
+
+    public static byte[] SignSm3WithSm2Asn1Rs(byte[] msg, byte[] userId, AsymmetricKeyParameter privateKey)
+    {
+        ISigner signer = SignerUtilities.GetSigner("SM3withSM2");
+        signer.Init(true, new ParametersWithID(privateKey, userId));
+        signer.BlockUpdate(msg, 0, msg.Length);
+        byte[] sig = signer.GenerateSignature();
+        return sig;
+    }
+
+    /**
+    *
+    * @param msg
+    * @param userId
+    * @param rs r||s,直接拼接byte数组的rs
+    * @param publicKey
+    * @return
+    */
+
+    public static bool VerifySm3WithSm2(byte[] msg, byte[] userId, byte[] rs, AsymmetricKeyParameter publicKey)
+    {
+        if (rs == null || msg == null || userId == null) return false;
+        if (rs.Length != RS_LEN * 2) return false;
+        return VerifySm3WithSm2Asn1Rs(msg, userId, RsPlainByteArrayToAsn1(rs), publicKey);
+    }
+
+    /**
+     *
+     * @param msg
+     * @param userId
+     * @param rs in <b>asn1 format</b>
+     * @param publicKey
+     * @return
+     */
+
+    public static bool VerifySm3WithSm2Asn1Rs(byte[] msg, byte[] userId, byte[] sign, AsymmetricKeyParameter publicKey)
+    {
+        ISigner signer = SignerUtilities.GetSigner("SM3withSM2");
+        signer.Init(false, new ParametersWithID(publicKey, userId));
+        signer.BlockUpdate(msg, 0, msg.Length);
+        return signer.VerifySignature(sign);
+    }
+
+    /**
+     * bc加解密使用旧标c1||c2||c3,此方法在加密后调用,将结果转化为c1||c3||c2
+     * @param c1c2c3
+     * @return
+     */
+
+    private static byte[] ChangeC1C2C3ToC1C3C2(byte[] c1c2c3)
+    {
+        int c1Len = (x9ECParameters.Curve.FieldSize + 7) / 8 * 2 + 1; //sm2p256v1的这个固定65。可看GMNamedCurves、ECCurve代码。
+        const int c3Len = 32; //new SM3Digest().getDigestSize();
+        byte[] result = new byte[c1c2c3.Length];
+        Buffer.BlockCopy(c1c2c3, 0, result, 0, c1Len); //c1
+        Buffer.BlockCopy(c1c2c3, c1c2c3.Length - c3Len, result, c1Len, c3Len); //c3
+        Buffer.BlockCopy(c1c2c3, c1Len, result, c1Len + c3Len, c1c2c3.Length - c1Len - c3Len); //c2
+        return result;
+    }
+
+    /**
+     * bc加解密使用旧标c1||c3||c2,此方法在解密前调用,将密文转化为c1||c2||c3再去解密
+     * @param c1c3c2
+     * @return
+     */
+
+    private static byte[] ChangeC1C3C2ToC1C2C3(byte[] c1c3c2)
+    {
+        int c1Len = (x9ECParameters.Curve.FieldSize + 7) / 8 * 2 + 1; //sm2p256v1的这个固定65。可看GMNamedCurves、ECCurve代码。
+        const int c3Len = 32; //new SM3Digest().GetDigestSize();
+        byte[] result = new byte[c1c3c2.Length];
+        Buffer.BlockCopy(c1c3c2, 0, result, 0, c1Len); //c1: 0->65
+        Buffer.BlockCopy(c1c3c2, c1Len + c3Len, result, c1Len, c1c3c2.Length - c1Len - c3Len); //c2
+        Buffer.BlockCopy(c1c3c2, c1Len, result, c1c3c2.Length - c3Len, c3Len); //c3
+        return result;
+    }
+
+    /**
+     * c1||c3||c2
+     * @param data
+     * @param key
+     * @return
+     */
+
+    public static byte[] Sm2Decrypt(byte[] data, AsymmetricKeyParameter key)
+    {
+        return Sm2DecryptOld(ChangeC1C3C2ToC1C2C3(data), key);
+    }
+
+    /**
+     * c1||c3||c2
+     * @param data
+     * @param key
+     * @return
+     */
+
+    public static byte[] Sm2Encrypt(byte[] data, AsymmetricKeyParameter key)
+    {
+        return ChangeC1C2C3ToC1C3C2(Sm2EncryptOld(data, key));
+    }
+
+    /**
+     * c1||c2||c3
+     * @param data
+     * @param key
+     * @return
+     */
+
+    public static byte[] Sm2EncryptOld(byte[] data, AsymmetricKeyParameter pubkey)
+    {
+        SM2Engine sm2Engine = new SM2Engine();
+        sm2Engine.Init(true, new ParametersWithRandom(pubkey, new SecureRandom()));
+        return sm2Engine.ProcessBlock(data, 0, data.Length);
+    }
+
+    /**
+     * c1||c2||c3
+     * @param data
+     * @param key
+     * @return
+     */
+
+    public static byte[] Sm2DecryptOld(byte[] data, AsymmetricKeyParameter key)
+    {
+        SM2Engine sm2Engine = new SM2Engine();
+        sm2Engine.Init(false, key);
+        return sm2Engine.ProcessBlock(data, 0, data.Length);
+    }
+
+    /**
+     * @param bytes
+     * @return
+     */
+
+    public static byte[] Sm3(byte[] bytes)
+    {
+        SM3Digest digest = new();
+        digest.BlockUpdate(bytes, 0, bytes.Length);
+        byte[] result = DigestUtilities.DoFinal(digest);
+        return result;
+    }
+
+    private const int RS_LEN = 32;
+
+    private static byte[] BigIntToFixexLengthBytes(BigInteger rOrS)
+    {
+        // for sm2p256v1, n is 00fffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54123,
+        // r and s are the result of mod n, so they should be less than n and have length<=32
+        byte[] rs = rOrS.ToByteArray();
+        if (rs.Length == RS_LEN) return rs;
+        else if (rs.Length == RS_LEN + 1 && rs[0] == 0) return Arrays.CopyOfRange(rs, 1, RS_LEN + 1);
+        else if (rs.Length < RS_LEN)
+        {
+            byte[] result = new byte[RS_LEN];
+            Arrays.Fill(result, (byte)0);
+            Buffer.BlockCopy(rs, 0, result, RS_LEN - rs.Length, rs.Length);
+            return result;
+        }
+        else
+        {
+            throw new ArgumentException("err rs: " + Hex.ToHexString(rs));
+        }
+    }
+
+    /**
+     * BC的SM3withSM2签名得到的结果的rs是asn1格式的,这个方法转化成直接拼接r||s
+     * @param rsDer rs in asn1 format
+     * @return sign result in plain byte array
+     */
+
+    private static byte[] RsAsn1ToPlainByteArray(byte[] rsDer)
+    {
+        Asn1Sequence seq = Asn1Sequence.GetInstance(rsDer);
+        byte[] r = BigIntToFixexLengthBytes(DerInteger.GetInstance(seq[0]).Value);
+        byte[] s = BigIntToFixexLengthBytes(DerInteger.GetInstance(seq[1]).Value);
+        byte[] result = new byte[RS_LEN * 2];
+        Buffer.BlockCopy(r, 0, result, 0, r.Length);
+        Buffer.BlockCopy(s, 0, result, RS_LEN, s.Length);
+        return result;
+    }
+
+    /**
+     * BC的SM3withSM2验签需要的rs是asn1格式的,这个方法将直接拼接r||s的字节数组转化成asn1格式
+     * @param sign in plain byte array
+     * @return rs result in asn1 format
+     */
+
+    private static byte[] RsPlainByteArrayToAsn1(byte[] sign)
+    {
+        if (sign.Length != RS_LEN * 2) throw new ArgumentException("err rs. ");
+        BigInteger r = new BigInteger(1, Arrays.CopyOfRange(sign, 0, RS_LEN));
+        BigInteger s = new BigInteger(1, Arrays.CopyOfRange(sign, RS_LEN, RS_LEN * 2));
+        Asn1EncodableVector v = new Asn1EncodableVector
+        {
+            new DerInteger(r),
+            new DerInteger(s)
+        };
+
+        return new DerSequence(v).GetEncoded("DER");
+    }
+
+    public static AsymmetricCipherKeyPair GenerateKeyPair()
+    {
+        ECKeyPairGenerator kpGen = new();
+        kpGen.Init(new ECKeyGenerationParameters(ecDomainParameters, new SecureRandom()));
+        return kpGen.GenerateKeyPair();
+    }
+
+    public static ECPrivateKeyParameters GetPrivatekeyFromD(BigInteger d)
+    {
+        return new ECPrivateKeyParameters(d, ecDomainParameters);
+    }
+
+    public static ECPublicKeyParameters GetPublickeyFromXY(BigInteger x, BigInteger y)
+    {
+        return new ECPublicKeyParameters(x9ECParameters.Curve.CreatePoint(x, y), ecDomainParameters);
+    }
+
+    public static AsymmetricKeyParameter GetPublickeyFromX509File(FileInfo file)
+    {
+        FileStream fileStream = null;
+        try
+        {
+            //file.DirectoryName + "\\" + file.Name
+            fileStream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read);
+            X509Certificate certificate = new X509CertificateParser().ReadCertificate(fileStream);
+            return certificate.GetPublicKey();
+        }
+        catch (Exception e)
+        {
+            //log.Error(file.Name + "读取失败,异常:" + e);
+        }
+        finally
+        {
+            if (fileStream != null)
+                fileStream.Close();
+        }
+        return null;
+    }
+
+    public class Sm2Cert
+    {
+        public AsymmetricKeyParameter privateKey;
+        public AsymmetricKeyParameter publicKey;
+        public string certId;
+    }
+
+    private static byte[] ToByteArray(int i)
+    {
+        byte[] byteArray = new byte[4];
+        byteArray[0] = (byte)(i >> 24);
+        byteArray[1] = (byte)((i & 0xFFFFFF) >> 16);
+        byteArray[2] = (byte)((i & 0xFFFF) >> 8);
+        byteArray[3] = (byte)(i & 0xFF);
+        return byteArray;
+    }
+
+    /**
+     * 字节数组拼接
+     *
+     * @param params
+     * @return
+     */
+
+    private static byte[] Join(params byte[][] byteArrays)
+    {
+        List<byte> byteSource = new();
+        for (int i = 0; i < byteArrays.Length; i++)
+        {
+            byteSource.AddRange(byteArrays[i]);
+        }
+        byte[] data = byteSource.ToArray();
+        return data;
+    }
+
+    /**
+     * 密钥派生函数
+     *
+     * @param Z
+     * @param klen
+     *            生成klen字节数长度的密钥
+     * @return
+     */
+
+    private static byte[] KDF(byte[] Z, int klen)
+    {
+        int ct = 1;
+        int end = (int)Math.Ceiling(klen * 1.0 / 32);
+        List<byte> byteSource = new();
+
+        for (int i = 1; i < end; i++)
+        {
+            byteSource.AddRange(Sm3(Join(Z, ToByteArray(ct))));
+            ct++;
+        }
+        byte[] last = Sm3(Join(Z, ToByteArray(ct)));
+        if (klen % 32 == 0)
+        {
+            byteSource.AddRange(last);
+        }
+        else
+            byteSource.AddRange(Arrays.CopyOfRange(last, 0, klen % 32));
+        return byteSource.ToArray();
+    }
+
+    public static byte[] Sm4DecryptCBC(byte[] keyBytes, byte[] cipher, byte[] iv, string algo)
+    {
+        if (keyBytes.Length != 16) throw new ArgumentException("err key length");
+        if (cipher.Length % 16 != 0 && algo.Contains("NoPadding")) throw new ArgumentException("err data length");
+
+        KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
+        IBufferedCipher c = CipherUtilities.GetCipher(algo);
+        if (iv == null) iv = ZeroIv(algo);
+        c.Init(false, new ParametersWithIV(key, iv));
+        return c.DoFinal(cipher);
+    }
+
+    public static byte[] Sm4EncryptCBC(byte[] keyBytes, byte[] plain, byte[] iv, string algo)
+    {
+        if (keyBytes.Length != 16) throw new ArgumentException("err key length");
+        if (plain.Length % 16 != 0 && algo.Contains("NoPadding")) throw new ArgumentException("err data length");
+
+        KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
+        IBufferedCipher c = CipherUtilities.GetCipher(algo);
+        if (iv == null) iv = ZeroIv(algo);
+        c.Init(true, new ParametersWithIV(key, iv));
+        return c.DoFinal(plain);
+    }
+
+    public static byte[] Sm4EncryptECB(byte[] keyBytes, byte[] plain, string algo)
+    {
+        if (keyBytes.Length != 16) throw new ArgumentException("err key length");
+        //NoPadding 的情况下需要校验数据长度是16的倍数.
+        if (plain.Length % 16 != 0 && algo.Contains("NoPadding")) throw new ArgumentException("err data length");
+
+        KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
+        IBufferedCipher c = CipherUtilities.GetCipher(algo);
+        c.Init(true, key);
+        return c.DoFinal(plain);
+    }
+
+    public static byte[] Sm4DecryptECB(byte[] keyBytes, byte[] cipher, string algo)
+    {
+        if (keyBytes.Length != 16) throw new ArgumentException("err key length");
+        if (cipher.Length % 16 != 0 && algo.Contains("NoPadding")) throw new ArgumentException("err data length");
+
+        KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
+        IBufferedCipher c = CipherUtilities.GetCipher(algo);
+        c.Init(false, key);
+        return c.DoFinal(cipher);
+    }
+
+    public const string SM4_ECB_NOPADDING = "SM4/ECB/NoPadding";
+    public const string SM4_CBC_NOPADDING = "SM4/CBC/NoPadding";
+    public const string SM4_CBC_PKCS7PADDING = "SM4/CBC/PKCS7Padding";
+
+    /**
+     * cfca官网CSP沙箱导出的sm2文件
+     * @param pem 二进制原文
+     * @param pwd 密码
+     * @return
+     */
+
+    public static Sm2Cert ReadSm2File(byte[] pem, string pwd)
+    {
+        Sm2Cert sm2Cert = new();
+
+        Asn1Sequence asn1Sequence = (Asn1Sequence)Asn1Object.FromByteArray(pem);
+        //            ASN1Integer asn1Integer = (ASN1Integer) asn1Sequence.getObjectAt(0); //version=1
+        Asn1Sequence priSeq = (Asn1Sequence)asn1Sequence[1];//private key
+        Asn1Sequence pubSeq = (Asn1Sequence)asn1Sequence[2];//public key and x509 cert
+
+        //            ASN1ObjectIdentifier sm2DataOid = (ASN1ObjectIdentifier) priSeq.getObjectAt(0);
+        //            ASN1ObjectIdentifier sm4AlgOid = (ASN1ObjectIdentifier) priSeq.getObjectAt(1);
+        Asn1OctetString priKeyAsn1 = (Asn1OctetString)priSeq[2];
+        byte[] key = KDF(System.Text.Encoding.UTF8.GetBytes(pwd), 32);
+        byte[] priKeyD = Sm4DecryptCBC(Arrays.CopyOfRange(key, 16, 32),
+                priKeyAsn1.GetOctets(),
+                Arrays.CopyOfRange(key, 0, 16), SM4_CBC_PKCS7PADDING);
+        sm2Cert.privateKey = GetPrivatekeyFromD(new BigInteger(1, priKeyD));
+        //            log.Info(Hex.toHexString(priKeyD));
+
+        //            ASN1ObjectIdentifier sm2DataOidPub = (ASN1ObjectIdentifier) pubSeq.getObjectAt(0);
+        Asn1OctetString pubKeyX509 = (Asn1OctetString)pubSeq[1];
+        X509Certificate x509 = new X509CertificateParser().ReadCertificate(pubKeyX509.GetOctets());
+        sm2Cert.publicKey = x509.GetPublicKey();
+        sm2Cert.certId = x509.SerialNumber.ToString(10); //这里转10进账,有啥其他进制要求的自己改改
+        return sm2Cert;
+    }
+
+    /**
+     *
+     * @param cert
+     * @return
+     */
+
+    public static Sm2Cert ReadSm2X509Cert(byte[] cert)
+    {
+        Sm2Cert sm2Cert = new();
+
+        X509Certificate x509 = new X509CertificateParser().ReadCertificate(cert);
+        sm2Cert.publicKey = x509.GetPublicKey();
+        sm2Cert.certId = x509.SerialNumber.ToString(10); //这里转10进账,有啥其他进制要求的自己改改
+        return sm2Cert;
+    }
+
+    public static byte[] ZeroIv(string algo)
+    {
+        IBufferedCipher cipher = CipherUtilities.GetCipher(algo);
+        int blockSize = cipher.GetBlockSize();
+        byte[] iv = new byte[blockSize];
+        Arrays.Fill(iv, (byte)0);
+        return iv;
+    }
+}

+ 119 - 0
Admin.NET/Admin.NET.Core/Util/GM/GMUtil.cs

@@ -0,0 +1,119 @@
+// 麻省理工学院许可证
+//
+// 版权所有 (c) 2021-2023 zuohuaijun,大名科技(天津)有限公司  联系电话/微信:18020030720  QQ:515096995
+//
+// 特此免费授予获得本软件的任何人以处理本软件的权利,但须遵守以下条件:在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
+//
+// 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
+// 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Admin.NET.Core;
+
+/// <summary>
+/// GM工具类
+/// </summary>
+public class GMUtil
+{
+    public const string SM4_key = "0123456789abcdeffedcba9876543210";
+    public const string SM4_iv = "595298c7c6fd271f0402f804c33d3f66";
+
+    /// <summary>
+    /// SM2加密
+    /// </summary>
+    /// <param name="publicKeyHex"></param>
+    /// <param name="data_string"></param>
+    /// <returns></returns>
+    public static string SM2Encrypt(string publicKeyHex, string data_string)
+    {
+        // 如果是130位公钥,.NET使用的话,把开头的04截取掉
+        if (publicKeyHex.Length == 130)
+        {
+            publicKeyHex = publicKeyHex.Substring(2, 128);
+        }
+        // 公钥X,前64位
+        string x = publicKeyHex.Substring(0, 64);
+        // 公钥Y,后64位
+        string y = publicKeyHex.Substring(64);
+        // 获取公钥对象
+        AsymmetricKeyParameter publicKey1 = GM.GetPublickeyFromXY(new BigInteger(x, 16), new BigInteger(y, 16));
+        // Sm2Encrypt: C1C3C2
+        // Sm2EncryptOld: C1C2C3
+        byte[] digestByte = GM.Sm2Encrypt(Hex.Decode(data_string), publicKey1);
+        string strSM2 = Hex.ToHexString(digestByte);
+        return strSM2;
+    }
+
+    /// <summary>
+    /// SM2解密
+    /// </summary>
+    /// <param name="privateKey_string"></param>
+    /// <param name="encryptedData_string"></param>
+    /// <returns></returns>
+    public static string SM2Decrypt(string privateKey_string, string encryptedData_string)
+    {
+        if (!encryptedData_string.StartsWith("04"))
+            encryptedData_string = "04" + encryptedData_string;
+        BigInteger d = new(privateKey_string, 16);
+        // 先拿到私钥对象,用ECPrivateKeyParameters 或 AsymmetricKeyParameter 都可以
+        // ECPrivateKeyParameters bcecPrivateKey = GmUtil.GetPrivatekeyFromD(d);
+        AsymmetricKeyParameter bcecPrivateKey = GM.GetPrivatekeyFromD(d);
+        byte[] byToDecrypt = Hex.Decode(encryptedData_string);
+        byte[] byDecrypted = GM.Sm2Decrypt(byToDecrypt, bcecPrivateKey);
+        string strDecrypted = Encoding.UTF8.GetString(byDecrypted);
+        return strDecrypted;
+    }
+
+    /// <summary>
+    /// SM4加密(ECB)
+    /// </summary>
+    /// <param name="plainText"></param>
+    /// <returns></returns>
+    public static string SM4EncryptECB(string plainText)
+    {
+        byte[] key = Hex.Decode(SM4_key);
+        byte[] bs = GM.Sm4EncryptECB(key, Hex.Decode(plainText), GM.SM4_ECB_NOPADDING);
+        return Hex.ToHexString(bs);
+    }
+
+    /// <summary>
+    /// SM4解密(ECB)
+    /// </summary>
+    /// <param name="cipherText"></param>
+    /// <returns></returns>
+    public static string SM4DecryptECB(string cipherText)
+    {
+        byte[] key = Hex.Decode(SM4_key);
+        byte[] bs = GM.Sm4DecryptECB(key, Hex.Decode(cipherText), GM.SM4_ECB_NOPADDING);
+        return Encoding.UTF8.GetString(bs);
+    }
+
+    /// <summary>
+    /// SM4加密(CBC)
+    /// </summary>
+    /// <param name="plainText"></param>
+    /// <returns></returns>
+    public static string SM4EncryptCBC(string plainText)
+    {
+        byte[] key = Hex.Decode(SM4_key);
+        byte[] iv = Hex.Decode(SM4_iv);
+        byte[] bs = GM.Sm4EncryptCBC(key, Hex.Decode(plainText), iv, GM.SM4_CBC_NOPADDING);
+        return Hex.ToHexString(bs);
+    }
+
+    /// <summary>
+    /// SM4解密(CBC)
+    /// </summary>
+    /// <param name="cipherText"></param>
+    /// <returns></returns>
+    public static string SM4DecryptCBC(string cipherText)
+    {
+        byte[] key = Hex.Decode(SM4_key);
+        byte[] iv = Hex.Decode(SM4_iv);
+        byte[] bs = GM.Sm4DecryptCBC(key, Hex.Decode(cipherText), iv, GM.SM4_CBC_NOPADDING);
+        return Encoding.UTF8.GetString(bs);
+    }
+}

+ 0 - 139
Admin.NET/Admin.NET.Core/Util/SM/Cipher.cs

@@ -1,139 +0,0 @@
-// 麻省理工学院许可证
-//
-// 版权所有 (c) 2021-2023 zuohuaijun,大名科技(天津)有限公司  联系电话/微信:18020030720  QQ:515096995
-//
-// 特此免费授予获得本软件的任何人以处理本软件的权利,但须遵守以下条件:在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
-//
-// 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
-// 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
-
-using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Math;
-using Org.BouncyCastle.Math.EC;
-
-namespace Admin.NET.Core;
-
-public class Cipher
-{
-    private int ct;
-    private ECPoint p2;
-    private SM3Digest sm3keybase;
-    private SM3Digest sm3c3;
-    private readonly byte[] key;
-    private byte keyOff;
-
-    public Cipher()
-    {
-        ct = 1;
-        key = new byte[32];
-        keyOff = 0;
-    }
-
-    public static byte[] ByteConvert32Bytes(BigInteger n)
-    {
-        if (n == null)
-            return null;
-
-        byte[] tmpd;
-        if (n.ToByteArray().Length == 33)
-        {
-            tmpd = new byte[32];
-            Array.Copy(n.ToByteArray(), 1, tmpd, 0, 32);
-        }
-        else if (n.ToByteArray().Length == 32)
-        {
-            tmpd = n.ToByteArray();
-        }
-        else
-        {
-            tmpd = new byte[32];
-            for (int i = 0; i < 32 - n.ToByteArray().Length; i++)
-            {
-                tmpd[i] = 0;
-            }
-            Array.Copy(n.ToByteArray(), 0, tmpd, 32 - n.ToByteArray().Length, n.ToByteArray().Length);
-        }
-        return tmpd;
-    }
-
-    private void Reset()
-    {
-        sm3keybase = new SM3Digest();
-        sm3c3 = new SM3Digest();
-
-        byte[] p = ByteConvert32Bytes(p2.Normalize().XCoord.ToBigInteger());
-        sm3keybase.BlockUpdate(p, 0, p.Length);
-        sm3c3.BlockUpdate(p, 0, p.Length);
-
-        p = ByteConvert32Bytes(p2.Normalize().YCoord.ToBigInteger());
-        sm3keybase.BlockUpdate(p, 0, p.Length);
-        ct = 1;
-        NextKey();
-    }
-
-    private void NextKey()
-    {
-        var sm3keycur = new SM3Digest(this.sm3keybase);
-        sm3keycur.Update((byte)(ct >> 24 & 0xff));
-        sm3keycur.Update((byte)(ct >> 16 & 0xff));
-        sm3keycur.Update((byte)(ct >> 8 & 0xff));
-        sm3keycur.Update((byte)(ct & 0xff));
-        sm3keycur.DoFinal(key, 0);
-        keyOff = 0;
-        ct++;
-    }
-
-    public ECPoint Init_enc(SM2 sm2, ECPoint userKey)
-    {
-        AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.GenerateKeyPair();
-        ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters)key.Private;
-        ECPublicKeyParameters ecpub = (ECPublicKeyParameters)key.Public;
-        BigInteger k = ecpriv.D;
-        ECPoint c1 = ecpub.Q;
-        p2 = userKey.Multiply(k);
-        Reset();
-        return c1;
-    }
-
-    public void Encrypt(byte[] data)
-    {
-        sm3c3.BlockUpdate(data, 0, data.Length);
-        for (int i = 0; i < data.Length; i++)
-        {
-            if (keyOff == key.Length)
-            {
-                NextKey();
-            }
-            data[i] ^= key[keyOff++];
-        }
-    }
-
-    public void Init_dec(BigInteger userD, ECPoint c1)
-    {
-        p2 = c1.Multiply(userD);
-        Reset();
-    }
-
-    public void Decrypt(byte[] data)
-    {
-        for (int i = 0; i < data.Length; i++)
-        {
-            if (keyOff == key.Length)
-            {
-                NextKey();
-            }
-            data[i] ^= key[keyOff++];
-        }
-
-        sm3c3.BlockUpdate(data, 0, data.Length);
-    }
-
-    public void Dofinal(byte[] c3)
-    {
-        byte[] p = ByteConvert32Bytes(p2.Normalize().YCoord.ToBigInteger());
-        sm3c3.BlockUpdate(p, 0, p.Length);
-        sm3c3.DoFinal(c3, 0);
-        Reset();
-    }
-}

+ 0 - 119
Admin.NET/Admin.NET.Core/Util/SM/SM2.cs

@@ -1,119 +0,0 @@
-// 麻省理工学院许可证
-//
-// 版权所有 (c) 2021-2023 zuohuaijun,大名科技(天津)有限公司  联系电话/微信:18020030720  QQ:515096995
-//
-// 特此免费授予获得本软件的任何人以处理本软件的权利,但须遵守以下条件:在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
-//
-// 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
-// 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
-
-using Org.BouncyCastle.Crypto.Generators;
-using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Math;
-using Org.BouncyCastle.Math.EC;
-using Org.BouncyCastle.Security;
-
-namespace Admin.NET.Core;
-
-public class SM2
-{
-    public static SM2 Instance
-    {
-        get
-        {
-            return new SM2();
-        }
-    }
-
-    public static SM2 InstanceTest
-    {
-        get
-        {
-            return new SM2();
-        }
-    }
-
-    public static readonly string[] sm2_param = {
-        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",// p,0
-        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",// a,1
-        "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",// b,2
-        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",// n,3
-        "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",// gx,4
-        "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0" // gy,5
-    };
-
-    public string[] ecc_param = sm2_param;
-
-    public readonly BigInteger ecc_p;
-    public readonly BigInteger ecc_a;
-    public readonly BigInteger ecc_b;
-    public readonly BigInteger ecc_n;
-    public readonly BigInteger ecc_gx;
-    public readonly BigInteger ecc_gy;
-
-    public readonly ECCurve ecc_curve;
-    public readonly ECPoint ecc_point_g;
-
-    public readonly ECDomainParameters ecc_bc_spec;
-
-    public readonly ECKeyPairGenerator ecc_key_pair_generator;
-
-    private SM2()
-    {
-        ecc_param = sm2_param;
-
-        ecc_p = new BigInteger(ecc_param[0], 16);
-        ecc_a = new BigInteger(ecc_param[1], 16);
-        ecc_b = new BigInteger(ecc_param[2], 16);
-        ecc_n = new BigInteger(ecc_param[3], 16);
-        ecc_gx = new BigInteger(ecc_param[4], 16);
-        ecc_gy = new BigInteger(ecc_param[5], 16);
-
-        ecc_curve = new FpCurve(ecc_p, ecc_a, ecc_b, null, null);
-        ecc_point_g = ecc_curve.CreatePoint(ecc_gx, ecc_gy);
-
-        ecc_bc_spec = new ECDomainParameters(ecc_curve, ecc_point_g, ecc_n);
-
-        ECKeyGenerationParameters ecc_ecgenparam;
-        ecc_ecgenparam = new ECKeyGenerationParameters(ecc_bc_spec, new SecureRandom());
-
-        ecc_key_pair_generator = new ECKeyPairGenerator();
-        ecc_key_pair_generator.Init(ecc_ecgenparam);
-    }
-
-    public virtual byte[] Sm2GetZ(byte[] userId, ECPoint userKey)
-    {
-        var sm3 = new SM3Digest();
-        byte[] p;
-        // userId length
-        int len = userId.Length * 8;
-        sm3.Update((byte)(len >> 8 & 0x00ff));
-        sm3.Update((byte)(len & 0x00ff));
-
-        // userId
-        sm3.BlockUpdate(userId, 0, userId.Length);
-
-        // a,b
-        p = ecc_a.ToByteArray();
-        sm3.BlockUpdate(p, 0, p.Length);
-        p = ecc_b.ToByteArray();
-        sm3.BlockUpdate(p, 0, p.Length);
-        // gx,gy
-        p = ecc_gx.ToByteArray();
-        sm3.BlockUpdate(p, 0, p.Length);
-        p = ecc_gy.ToByteArray();
-        sm3.BlockUpdate(p, 0, p.Length);
-
-        // x,y
-        p = userKey.AffineXCoord.ToBigInteger().ToByteArray();
-        sm3.BlockUpdate(p, 0, p.Length);
-        p = userKey.AffineYCoord.ToBigInteger().ToByteArray();
-        sm3.BlockUpdate(p, 0, p.Length);
-
-        // Z
-        byte[] md = new byte[sm3.GetDigestSize()];
-        sm3.DoFinal(md, 0);
-
-        return md;
-    }
-}

+ 0 - 176
Admin.NET/Admin.NET.Core/Util/SM/SM2Util.cs

@@ -1,176 +0,0 @@
-// 麻省理工学院许可证
-//
-// 版权所有 (c) 2021-2023 zuohuaijun,大名科技(天津)有限公司  联系电话/微信:18020030720  QQ:515096995
-//
-// 特此免费授予获得本软件的任何人以处理本软件的权利,但须遵守以下条件:在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
-//
-// 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
-// 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
-
-using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Math;
-using Org.BouncyCastle.Math.EC;
-using Org.BouncyCastle.Utilities.Encoders;
-
-namespace Admin.NET.Core;
-
-/// <summary>
-/// SM2工具类
-/// </summary>
-public class SM2Util
-{
-    /// <summary>
-    /// 加密
-    /// </summary>
-    /// <param name="publicKey_string"></param>
-    /// <param name="data_string"></param>
-    /// <returns></returns>
-    public static string Encrypt(string publicKey_string, string data_string)
-    {
-        var publicKey = Hex.Decode(publicKey_string);
-        var data = Encoding.UTF8.GetBytes(data_string);
-        return Encrypt(publicKey, data);
-    }
-
-    /// <summary>
-    /// 解密
-    /// </summary>
-    /// <param name="privateKey_string"></param>
-    /// <param name="encryptedData_string"></param>
-    /// <returns></returns>
-    public static string Decrypt(string privateKey_string, string encryptedData_string)
-    {
-        var privateKey = Hex.Decode(privateKey_string);
-        var encryptedData = Hex.Decode(encryptedData_string);
-        var de_str = SM2Util.Decrypt(privateKey, encryptedData);
-        string plainText = Encoding.UTF8.GetString(de_str);
-        return plainText;
-    }
-
-    public static void GenerateKeyPair()
-    {
-        SM2 sm2 = SM2.Instance;
-        AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.GenerateKeyPair();
-        ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters)key.Private;
-        ECPublicKeyParameters ecpub = (ECPublicKeyParameters)key.Public;
-        BigInteger privateKey = ecpriv.D;
-        ECPoint publicKey = ecpub.Q;
-
-        Console.Out.WriteLine("公钥: " + Encoding.ASCII.GetString(Hex.Encode(publicKey.GetEncoded())).ToUpper());
-        Console.Out.WriteLine("私钥: " + Encoding.ASCII.GetString(Hex.Encode(privateKey.ToByteArray())).ToUpper());
-    }
-
-    public static string Encrypt(byte[] publicKey, byte[] data)
-    {
-        if (null == publicKey || publicKey.Length == 0)
-        {
-            return null;
-        }
-        if (data == null || data.Length == 0)
-        {
-            return null;
-        }
-
-        byte[] source = new byte[data.Length];
-        Array.Copy(data, 0, source, 0, data.Length);
-
-        var cipher = new Cipher();
-        SM2 sm2 = SM2.Instance;
-
-        ECPoint userKey = sm2.ecc_curve.DecodePoint(publicKey);
-
-        ECPoint c1 = cipher.Init_enc(sm2, userKey);
-        cipher.Encrypt(source);
-
-        byte[] c3 = new byte[32];
-        cipher.Dofinal(c3);
-
-        string sc1 = Encoding.ASCII.GetString(Hex.Encode(c1.GetEncoded()));
-        string sc2 = Encoding.ASCII.GetString(Hex.Encode(source));
-        string sc3 = Encoding.ASCII.GetString(Hex.Encode(c3));
-
-        return (sc1 + sc2 + sc3).ToUpper();
-    }
-
-    public static byte[] Decrypt(byte[] privateKey, byte[] encryptedData)
-    {
-        if (null == privateKey || privateKey.Length == 0)
-        {
-            return null;
-        }
-        if (encryptedData == null || encryptedData.Length == 0)
-        {
-            return null;
-        }
-
-        string data = Encoding.ASCII.GetString(Hex.Encode(encryptedData));
-
-        byte[] c1Bytes = Hex.Decode(Encoding.ASCII.GetBytes(data.Substring(0, 130)));
-        int c2Len = encryptedData.Length - 97;
-        byte[] c2 = Hex.Decode(Encoding.ASCII.GetBytes(data.Substring(130, 2 * c2Len)));
-        byte[] c3 = Hex.Decode(Encoding.ASCII.GetBytes(data.Substring(130 + 2 * c2Len, 64)));
-
-        SM2 sm2 = SM2.Instance;
-        var userD = new BigInteger(1, privateKey);
-
-        ECPoint c1 = sm2.ecc_curve.DecodePoint(c1Bytes);
-        var cipher = new Cipher();
-        cipher.Init_dec(userD, c1);
-        cipher.Decrypt(c2);
-        cipher.Dofinal(c3);
-
-        return c2;
-    }
-
-    //[STAThread]
-    //public static void Main()
-    //{
-    //    GenerateKeyPair();
-
-    //    String plainText = "ererfeiisgod";
-    //    byte[] sourceData = Encoding.Default.GetBytes(plainText);
-
-    //    //下面的秘钥可以使用generateKeyPair()生成的秘钥内容
-    //    // 国密规范正式私钥
-    //    String prik = "3690655E33D5EA3D9A4AE1A1ADD766FDEA045CDEAA43A9206FB8C430CEFE0D94";
-    //    // 国密规范正式公钥
-    //    String pubk = "04F6E0C3345AE42B51E06BF50B98834988D54EBC7460FE135A48171BC0629EAE205EEDE253A530608178A98F1E19BB737302813BA39ED3FA3C51639D7A20C7391A";
-
-    //    System.Console.Out.WriteLine("加密: ");
-    //    String cipherText = SM2Utils.Encrypt(Hex.Decode(pubk), sourceData);
-    //    System.Console.Out.WriteLine(cipherText);
-    //    System.Console.Out.WriteLine("解密: ");
-    //    plainText = Encoding.Default.GetString(SM2Utils.Decrypt(Hex.Decode(prik), Hex.Decode(cipherText)));
-    //    System.Console.Out.WriteLine(plainText);
-
-    //    Console.ReadLine();
-    //}
-
-    /// <summary>
-    /// SM2加密
-    /// </summary>
-    /// <param name="plainText">明文</param>
-    /// <returns>密文</returns>
-    public static String 加密(String plainText)
-    {
-        // 国密规范正式公钥
-        String pubk = "04F6E0C3345AE42B51E06BF50B98834988D54EBC7460FE135A48171BC0629EAE205EEDE253A530608178A98F1E19BB737302813BA39ED3FA3C51639D7A20C7391A";
-        byte[] sourceData = Encoding.Default.GetBytes(plainText);
-        String cipherText = SM2Util.Encrypt(Hex.Decode(pubk), sourceData);
-        return cipherText;
-    }
-
-    /// <summary>
-    /// SM2解密
-    /// </summary>
-    /// <param name="cipherText">密文</param>
-    /// <returns>明文</returns>
-    public static string 解密(String cipherText)
-    {
-        // 国密规范正式私钥
-        String prik = "3690655E33D5EA3D9A4AE1A1ADD766FDEA045CDEAA43A9206FB8C430CEFE0D94";
-        String plainText = Encoding.Default.GetString(SM2Util.Decrypt(Hex.Decode(prik), Hex.Decode(cipherText)));
-        return plainText;
-    }
-}

+ 0 - 408
Admin.NET/Admin.NET.Core/Util/SM/SM3.cs

@@ -1,408 +0,0 @@
-// 麻省理工学院许可证
-//
-// 版权所有 (c) 2021-2023 zuohuaijun,大名科技(天津)有限公司  联系电话/微信:18020030720  QQ:515096995
-//
-// 特此免费授予获得本软件的任何人以处理本软件的权利,但须遵守以下条件:在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
-//
-// 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
-// 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
-
-using Org.BouncyCastle.Crypto;
-
-namespace Admin.NET.Core;
-
-public abstract class GeneralDigest : IDigest
-{
-    private const int BYTE_LENGTH = 64;
-
-    private readonly byte[] xBuf;
-    private int xBufOff;
-
-    private long byteCount;
-
-    internal GeneralDigest()
-    {
-        xBuf = new byte[4];
-    }
-
-    internal GeneralDigest(GeneralDigest t)
-    {
-        xBuf = new byte[t.xBuf.Length];
-        Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length);
-
-        xBufOff = t.xBufOff;
-        byteCount = t.byteCount;
-    }
-
-    public void Update(byte input)
-    {
-        xBuf[xBufOff++] = input;
-
-        if (xBufOff == xBuf.Length)
-        {
-            ProcessWord(xBuf, 0);
-            xBufOff = 0;
-        }
-
-        byteCount++;
-    }
-
-    public void BlockUpdate(byte[] input, int inOff, int length)
-    {
-        //
-        // fill the current word
-        //
-        while ((xBufOff != 0) && (length > 0))
-        {
-            Update(input[inOff]);
-            inOff++;
-            length--;
-        }
-
-        //
-        // process whole words.
-        //
-        while (length > xBuf.Length)
-        {
-            ProcessWord(input, inOff);
-
-            inOff += xBuf.Length;
-            length -= xBuf.Length;
-            byteCount += xBuf.Length;
-        }
-
-        //
-        // load in the remainder.
-        //
-        while (length > 0)
-        {
-            Update(input[inOff]);
-
-            inOff++;
-            length--;
-        }
-    }
-
-    public void Finish()
-    {
-        long bitLength = (byteCount << 3);
-
-        //
-        // add the pad bytes.
-        //
-        Update(unchecked((byte)128));
-
-        while (xBufOff != 0) Update(unchecked((byte)0));
-        ProcessLength(bitLength);
-        ProcessBlock();
-    }
-
-    public virtual void Reset()
-    {
-        byteCount = 0;
-        xBufOff = 0;
-        Array.Clear(xBuf, 0, xBuf.Length);
-    }
-
-    public int GetByteLength()
-    {
-        return BYTE_LENGTH;
-    }
-
-    internal abstract void ProcessWord(byte[] input, int inOff);
-
-    internal abstract void ProcessLength(long bitLength);
-
-    internal abstract void ProcessBlock();
-
-    public abstract string AlgorithmName { get; }
-
-    public abstract int GetDigestSize();
-
-    public abstract void BlockUpdate(ReadOnlySpan<byte> input);
-
-    public abstract int DoFinal(byte[] output, int outOff);
-
-    public abstract int DoFinal(Span<byte> output);
-}
-
-public class SupportClass
-{
-    /// <summary>
-    /// Performs an unsigned bitwise right shift with the specified number
-    /// </summary>
-    /// <param name="number">Number to operate on</param>
-    /// <param name="bits">Ammount of bits to shift</param>
-    /// <returns>The resulting number from the shift operation</returns>
-    public static int URShift(int number, int bits)
-    {
-        if (number >= 0)
-            return number >> bits;
-        else
-            return (number >> bits) + (2 << ~bits);
-    }
-
-    /// <summary>
-    /// Performs an unsigned bitwise right shift with the specified number
-    /// </summary>
-    /// <param name="number">Number to operate on</param>
-    /// <param name="bits">Ammount of bits to shift</param>
-    /// <returns>The resulting number from the shift operation</returns>
-    public static int URShift(int number, long bits)
-    {
-        return URShift(number, (int)bits);
-    }
-
-    /// <summary>
-    /// Performs an unsigned bitwise right shift with the specified number
-    /// </summary>
-    /// <param name="number">Number to operate on</param>
-    /// <param name="bits">Ammount of bits to shift</param>
-    /// <returns>The resulting number from the shift operation</returns>
-    public static long URShift(long number, int bits)
-    {
-        if (number >= 0)
-            return number >> bits;
-        else
-            return (number >> bits) + (2L << ~bits);
-    }
-
-    /// <summary>
-    /// Performs an unsigned bitwise right shift with the specified number
-    /// </summary>
-    /// <param name="number">Number to operate on</param>
-    /// <param name="bits">Ammount of bits to shift</param>
-    /// <returns>The resulting number from the shift operation</returns>
-    public static long URShift(long number, long bits)
-    {
-        return URShift(number, (int)bits);
-    }
-}
-
-public class SM3Digest : GeneralDigest
-{
-    public override string AlgorithmName
-    {
-        get
-        {
-            return "SM3";
-        }
-    }
-
-    public override int GetDigestSize()
-    {
-        return DIGEST_LENGTH;
-    }
-
-    private const int DIGEST_LENGTH = 32;
-
-    private static readonly int[] v0 = new int[] { 0x7380166f, 0x4914b2b9, 0x172442d7, unchecked((int)0xda8a0600), unchecked((int)0xa96f30bc), 0x163138aa, unchecked((int)0xe38dee4d), unchecked((int)0xb0fb0e4e) };
-
-    private readonly int[] v = new int[8];
-    private readonly int[] v_ = new int[8];
-
-    private static readonly int[] X0 = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-    private readonly int[] X = new int[68];
-    private int xOff;
-
-    private readonly int T_00_15 = 0x79cc4519;
-    private readonly int T_16_63 = 0x7a879d8a;
-
-    public SM3Digest()
-    {
-        Reset();
-    }
-
-    public SM3Digest(SM3Digest t) : base(t)
-    {
-        Array.Copy(t.X, 0, X, 0, t.X.Length);
-        xOff = t.xOff;
-
-        Array.Copy(t.v, 0, v, 0, t.v.Length);
-    }
-
-    public override void Reset()
-    {
-        base.Reset();
-
-        Array.Copy(v0, 0, v, 0, v0.Length);
-
-        xOff = 0;
-        Array.Copy(X0, 0, X, 0, X0.Length);
-    }
-
-    internal override void ProcessBlock()
-    {
-        int i;
-
-        int[] ww = X;
-        int[] ww_ = new int[64];
-
-        for (i = 16; i < 68; i++)
-        {
-            ww[i] = P1(ww[i - 16] ^ ww[i - 9] ^ (ROTATE(ww[i - 3], 15))) ^ (ROTATE(ww[i - 13], 7)) ^ ww[i - 6];
-        }
-
-        for (i = 0; i < 64; i++)
-        {
-            ww_[i] = ww[i] ^ ww[i + 4];
-        }
-
-        int[] vv = v;
-        int[] vv_ = v_;
-
-        Array.Copy(vv, 0, vv_, 0, v0.Length);
-
-        int SS1, SS2, TT1, TT2, aaa;
-        for (i = 0; i < 16; i++)
-        {
-            aaa = ROTATE(vv_[0], 12);
-            SS1 = aaa + vv_[4] + ROTATE(T_00_15, i);
-            SS1 = ROTATE(SS1, 7);
-            SS2 = SS1 ^ aaa;
-
-            TT1 = FF_00_15(vv_[0], vv_[1], vv_[2]) + vv_[3] + SS2 + ww_[i];
-            TT2 = GG_00_15(vv_[4], vv_[5], vv_[6]) + vv_[7] + SS1 + ww[i];
-            vv_[3] = vv_[2];
-            vv_[2] = ROTATE(vv_[1], 9);
-            vv_[1] = vv_[0];
-            vv_[0] = TT1;
-            vv_[7] = vv_[6];
-            vv_[6] = ROTATE(vv_[5], 19);
-            vv_[5] = vv_[4];
-            vv_[4] = P0(TT2);
-        }
-        for (i = 16; i < 64; i++)
-        {
-            aaa = ROTATE(vv_[0], 12);
-            SS1 = aaa + vv_[4] + ROTATE(T_16_63, i);
-            SS1 = ROTATE(SS1, 7);
-            SS2 = SS1 ^ aaa;
-
-            TT1 = FF_16_63(vv_[0], vv_[1], vv_[2]) + vv_[3] + SS2 + ww_[i];
-            TT2 = GG_16_63(vv_[4], vv_[5], vv_[6]) + vv_[7] + SS1 + ww[i];
-            vv_[3] = vv_[2];
-            vv_[2] = ROTATE(vv_[1], 9);
-            vv_[1] = vv_[0];
-            vv_[0] = TT1;
-            vv_[7] = vv_[6];
-            vv_[6] = ROTATE(vv_[5], 19);
-            vv_[5] = vv_[4];
-            vv_[4] = P0(TT2);
-        }
-        for (i = 0; i < 8; i++)
-        {
-            vv[i] ^= vv_[i];
-        }
-
-        // Reset
-        xOff = 0;
-        Array.Copy(X0, 0, X, 0, X0.Length);
-    }
-
-    internal override void ProcessWord(byte[] in_Renamed, int inOff)
-    {
-        int n = in_Renamed[inOff] << 24;
-        n |= (in_Renamed[++inOff] & 0xff) << 16;
-        n |= (in_Renamed[++inOff] & 0xff) << 8;
-        n |= (in_Renamed[++inOff] & 0xff);
-        X[xOff] = n;
-
-        if (++xOff == 16)
-        {
-            ProcessBlock();
-        }
-    }
-
-    internal override void ProcessLength(long bitLength)
-    {
-        if (xOff > 14)
-        {
-            ProcessBlock();
-        }
-
-        X[14] = (int)(SupportClass.URShift(bitLength, 32));
-        X[15] = (int)(bitLength & unchecked((int)0xffffffff));
-    }
-
-    public static void IntToBigEndian(int n, byte[] bs, int off)
-    {
-        bs[off] = (byte)(SupportClass.URShift(n, 24));
-        bs[++off] = (byte)(SupportClass.URShift(n, 16));
-        bs[++off] = (byte)(SupportClass.URShift(n, 8));
-        bs[++off] = (byte)(n);
-    }
-
-    public override int DoFinal(byte[] out_Renamed, int outOff)
-    {
-        Finish();
-
-        for (int i = 0; i < 8; i++)
-        {
-            IntToBigEndian(v[i], out_Renamed, outOff + i * 4);
-        }
-
-        Reset();
-
-        return DIGEST_LENGTH;
-    }
-
-    private static int ROTATE(int x, int n)
-    {
-        return (x << n) | (SupportClass.URShift(x, (32 - n)));
-    }
-
-    private static int P0(int X)
-    {
-        return ((X) ^ ROTATE((X), 9) ^ ROTATE((X), 17));
-    }
-
-    private static int P1(int X)
-    {
-        return ((X) ^ ROTATE((X), 15) ^ ROTATE((X), 23));
-    }
-
-    private static int FF_00_15(int X, int Y, int Z)
-    {
-        return (X ^ Y ^ Z);
-    }
-
-    private static int FF_16_63(int X, int Y, int Z)
-    {
-        return ((X & Y) | (X & Z) | (Y & Z));
-    }
-
-    private static int GG_00_15(int X, int Y, int Z)
-    {
-        return (X ^ Y ^ Z);
-    }
-
-    private static int GG_16_63(int X, int Y, int Z)
-    {
-        return ((X & Y) | (~X & Z));
-    }
-
-    public override void BlockUpdate(ReadOnlySpan<byte> input)
-    {
-    }
-
-    public override int DoFinal(Span<byte> output)
-    {
-        return DIGEST_LENGTH;
-    }
-
-    //[STAThread]
-    //public static void  Main()
-    //{
-    //    byte[] md = new byte[32];
-    //    byte[] msg1 = Encoding.Default.GetBytes("ererfeiisgod");
-    //    SM3Digest sm3 = new SM3Digest();
-    //    sm3.BlockUpdate(msg1, 0, msg1.Length);
-    //    sm3.DoFinal(md, 0);
-    //    System.String s = new UTF8Encoding().GetString(Hex.Encode(md));
-    //    System.Console.Out.WriteLine(s.ToUpper());
-
-    //    Console.ReadLine();
-    //}
-}

+ 0 - 37
Admin.NET/Admin.NET.Core/Util/SM/SM3Util.cs

@@ -1,37 +0,0 @@
-// 麻省理工学院许可证
-//
-// 版权所有 (c) 2021-2023 zuohuaijun,大名科技(天津)有限公司  联系电话/微信:18020030720  QQ:515096995
-//
-// 特此免费授予获得本软件的任何人以处理本软件的权利,但须遵守以下条件:在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
-//
-// 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
-// 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
-
-using Org.BouncyCastle.Utilities.Encoders;
-
-namespace Admin.NET.Core;
-
-/// <summary>
-/// SM3工具类
-/// </summary>
-public class SM3Util
-{
-    public string secretKey = "";
-
-    public string 加密(string data)
-    {
-        byte[] msg1 = Encoding.Default.GetBytes(data);
-        //byte[] key1 = Encoding.Default.GetBytes(secretKey);
-
-        //var keyParameter = new KeyParameter(key1);
-        var sm3 = new SM3Digest();
-
-        //HMac mac = new HMac(sm3); // 带密钥的杂凑算法
-        //mac.Init(keyParameter);
-        sm3.BlockUpdate(msg1, 0, msg1.Length);
-        // byte[] result = new byte[sm3.GetMacSize()];
-        byte[] result = new byte[sm3.GetDigestSize()];
-        sm3.DoFinal(result, 0);
-        return Encoding.ASCII.GetString(Hex.Encode(result));
-    }
-}

+ 0 - 345
Admin.NET/Admin.NET.Core/Util/SM/SM4.cs

@@ -1,345 +0,0 @@
-// 麻省理工学院许可证
-//
-// 版权所有 (c) 2021-2023 zuohuaijun,大名科技(天津)有限公司  联系电话/微信:18020030720  QQ:515096995
-//
-// 特此免费授予获得本软件的任何人以处理本软件的权利,但须遵守以下条件:在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
-//
-// 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
-// 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
-
-namespace Admin.NET.Core;
-
-public class SM4
-{
-    public const int SM4_ENCRYPT = 1;
-    public const int SM4_DECRYPT = 0;
-
-    // JS前后端加密不一样
-    public bool FOR_JAVASCRIPT = false;
-
-    private long GET_ULONG_BE(byte[] b, int i)
-    {
-        long n = 0;
-        if (FOR_JAVASCRIPT)
-        {
-            n = (b[i] & 0xff) << 24 | ((b[i + 1] & 0xff) << 16) | ((b[i + 2] & 0xff) << 8) | (b[i + 3] & 0xff) & 0xff;
-        }
-        else
-        {
-            n = (long)(b[i] & 0xff) << 24 | (long)((b[i + 1] & 0xff) << 16) | (long)((b[i + 2] & 0xff) << 8) | b[i + 3] & 0xff & 0xffffffffL;
-        }
-        return n;
-    }
-
-    private void PUT_ULONG_BE(long n, byte[] b, int i)
-    {
-        b[i] = (byte)(int)(0xFF & n >> 24);
-        b[i + 1] = (byte)(int)(0xFF & n >> 16);
-        b[i + 2] = (byte)(int)(0xFF & n >> 8);
-        b[i + 3] = (byte)(int)(0xFF & n);
-    }
-
-    private long SHL(long x, int n)
-    {
-        return (x & 0xFFFFFFFF) << n;
-    }
-
-    private long ROTL(long x, int n)
-    {
-        return SHL(x, n) | x >> (32 - n);
-    }
-
-    private void SWAP(long[] sk, int i)
-    {
-        long t = sk[i];
-        sk[i] = sk[(31 - i)];
-        sk[(31 - i)] = t;
-    }
-
-    public byte[] SboxTable = new byte[] {
-        0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
-        0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
-        0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
-        0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
-        0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a,
-        0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
-        0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95,
-        0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
-        0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba,
-        0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
-        0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b,
-        0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
-        0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2,
-        0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
-        0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
-        0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
-        0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5,
-        0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
-        0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
-        0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
-        0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60,
-        0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
-        0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f,
-        0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
-        0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f,
-        0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
-        0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd,
-        0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
-        0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e,
-        0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
-        0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20,
-        0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
-    };
-
-    public uint[] FK = {
-        0xa3b1bac6,
-        0x56aa3350,
-        0x677d9197,
-        0xb27022dc
-    };
-
-    public uint[] CK = {
-        0x00070e15,0x1c232a31,0x383f464d,0x545b6269,
-        0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,
-        0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,
-        0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,
-        0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,
-        0x30373e45,0x4c535a61,0x686f767d,0x848b9299,
-        0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,
-        0x10171e25,0x2c333a41,0x484f565d,0x646b7279
-    };
-
-    private byte Sm4Sbox(byte inch)
-    {
-        int i = inch & 0xFF;
-        byte retVal = SboxTable[i];
-        return retVal;
-    }
-
-    private long Sm4Lt(long ka)
-    {
-        byte[] a = new byte[4];
-        byte[] b = new byte[4];
-        PUT_ULONG_BE(ka, a, 0);
-        b[0] = Sm4Sbox(a[0]);
-        b[1] = Sm4Sbox(a[1]);
-        b[2] = Sm4Sbox(a[2]);
-        b[3] = Sm4Sbox(a[3]);
-        long bb = GET_ULONG_BE(b, 0);
-        long c = bb ^ ROTL(bb, 2) ^ ROTL(bb, 10) ^ ROTL(bb, 18) ^ ROTL(bb, 24);
-        return c;
-    }
-
-    private long Sm4F(long x0, long x1, long x2, long x3, long rk)
-    {
-        return x0 ^ Sm4Lt(x1 ^ x2 ^ x3 ^ rk);
-    }
-
-    private long Sm4CalciRK(long ka)
-    {
-        byte[] a = new byte[4];
-        byte[] b = new byte[4];
-        PUT_ULONG_BE(ka, a, 0);
-        b[0] = Sm4Sbox(a[0]);
-        b[1] = Sm4Sbox(a[1]);
-        b[2] = Sm4Sbox(a[2]);
-        b[3] = Sm4Sbox(a[3]);
-        long bb = GET_ULONG_BE(b, 0);
-        long rk = bb ^ ROTL(bb, 13) ^ ROTL(bb, 23);
-        return rk;
-    }
-
-    private void Sm4_setkey(long[] SK, byte[] key)
-    {
-        long[] MK = new long[4];
-        long[] k = new long[36];
-        int i = 0;
-        MK[0] = GET_ULONG_BE(key, 0);
-        MK[1] = GET_ULONG_BE(key, 4);
-        MK[2] = GET_ULONG_BE(key, 8);
-        MK[3] = GET_ULONG_BE(key, 12);
-        k[0] = MK[0] ^ (long)FK[0];
-        k[1] = MK[1] ^ (long)FK[1];
-        k[2] = MK[2] ^ (long)FK[2];
-        k[3] = MK[3] ^ (long)FK[3];
-        for (; i < 32; i++)
-        {
-            k[(i + 4)] = (k[i] ^ Sm4CalciRK(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^ (long)CK[i]));
-            SK[i] = k[(i + 4)];
-        }
-    }
-
-    private void Sm4_one_round(long[] sk, byte[] input, byte[] output)
-    {
-        int i = 0;
-        long[] ulbuf = new long[36];
-        ulbuf[0] = GET_ULONG_BE(input, 0);
-        ulbuf[1] = GET_ULONG_BE(input, 4);
-        ulbuf[2] = GET_ULONG_BE(input, 8);
-        ulbuf[3] = GET_ULONG_BE(input, 12);
-        while (i < 32)
-        {
-            ulbuf[(i + 4)] = Sm4F(ulbuf[i], ulbuf[(i + 1)], ulbuf[(i + 2)], ulbuf[(i + 3)], sk[i]);
-            i++;
-        }
-        PUT_ULONG_BE(ulbuf[35], output, 0);
-        PUT_ULONG_BE(ulbuf[34], output, 4);
-        PUT_ULONG_BE(ulbuf[33], output, 8);
-        PUT_ULONG_BE(ulbuf[32], output, 12);
-    }
-
-    private static byte[] Padding(byte[] input, int mode)
-    {
-        if (input == null)
-        {
-            return null;
-        }
-
-        byte[] ret;
-        if (mode == SM4_ENCRYPT)
-        {
-            int p = 16 - input.Length % 16;
-            ret = new byte[input.Length + p];
-            Array.Copy(input, 0, ret, 0, input.Length);
-            for (int i = 0; i < p; i++)
-            {
-                ret[input.Length + i] = (byte)p;
-            }
-        }
-        else
-        {
-            int p = input[input.Length - 1];
-            ret = new byte[input.Length - p];
-            Array.Copy(input, 0, ret, 0, input.Length - p);
-        }
-        return ret;
-    }
-
-    public void Sm4_setkey_enc(SM4_Context ctx, byte[] key)
-    {
-        ctx.mode = SM4_ENCRYPT;
-        Sm4_setkey(ctx.sk, key);
-    }
-
-    public void Sm4_setkey_dec(SM4_Context ctx, byte[] key)
-    {
-        ctx.mode = SM4_DECRYPT;
-        Sm4_setkey(ctx.sk, key);
-        int i;
-        for (i = 0; i < 16; i++)
-        {
-            SWAP(ctx.sk, i);
-        }
-    }
-
-    public byte[] Sm4_crypt_ecb(SM4_Context ctx, byte[] input)
-    {
-        if ((ctx.isPadding) && (ctx.mode == SM4_ENCRYPT))
-        {
-            input = Padding(input, SM4_ENCRYPT);
-        }
-
-        int length = input.Length;
-        byte[] bins = new byte[length];
-        Array.Copy(input, 0, bins, 0, length);
-        byte[] bous = new byte[length];
-        for (int i = 0; length > 0; length -= 16, i++)
-        {
-            byte[] inBytes = new byte[16];
-            byte[] outBytes = new byte[16];
-            Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length);
-            Sm4_one_round(ctx.sk, inBytes, outBytes);
-            Array.Copy(outBytes, 0, bous, i * 16, length > 16 ? 16 : length);
-        }
-
-        if (ctx.isPadding && ctx.mode == SM4_DECRYPT)
-        {
-            bous = Padding(bous, SM4_DECRYPT);
-        }
-        return bous;
-    }
-
-    public byte[] Sm4_crypt_cbc(SM4_Context ctx, byte[] iv, byte[] input)
-    {
-        if (ctx.isPadding && ctx.mode == SM4_ENCRYPT)
-        {
-            input = Padding(input, SM4_ENCRYPT);
-        }
-
-        int i = 0;
-        int length = input.Length;
-        byte[] bins = new byte[length];
-        Array.Copy(input, 0, bins, 0, length);
-        var bousList = new List<byte>();
-        if (ctx.mode == SM4_ENCRYPT)
-        {
-            for (int j = 0; length > 0; length -= 16, j++)
-            {
-                byte[] inBytes = new byte[16];
-                byte[] outBytes = new byte[16];
-                byte[] out1 = new byte[16];
-
-                Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length);
-                for (i = 0; i < 16; i++)
-                {
-                    outBytes[i] = ((byte)(inBytes[i] ^ iv[i]));
-                }
-                Sm4_one_round(ctx.sk, outBytes, out1);
-                Array.Copy(out1, 0, iv, 0, 16);
-                for (int k = 0; k < 16; k++)
-                {
-                    bousList.Add(out1[k]);
-                }
-            }
-        }
-        else
-        {
-            byte[] temp = new byte[16];
-            for (int j = 0; length > 0; length -= 16, j++)
-            {
-                byte[] inBytes = new byte[16];
-                byte[] outBytes = new byte[16];
-                byte[] out1 = new byte[16];
-
-                Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length);
-                Array.Copy(inBytes, 0, temp, 0, 16);
-                Sm4_one_round(ctx.sk, inBytes, outBytes);
-                for (i = 0; i < 16; i++)
-                {
-                    out1[i] = ((byte)(outBytes[i] ^ iv[i]));
-                }
-                Array.Copy(temp, 0, iv, 0, 16);
-                for (int k = 0; k < 16; k++)
-                {
-                    bousList.Add(out1[k]);
-                }
-            }
-        }
-
-        if (ctx.isPadding && ctx.mode == SM4_DECRYPT)
-        {
-            byte[] bous = Padding(bousList.ToArray(), SM4_DECRYPT);
-            return bous;
-        }
-        else
-        {
-            return bousList.ToArray();
-        }
-    }
-}
-
-public class SM4_Context
-{
-    public int mode;
-
-    public long[] sk;
-
-    public bool isPadding;
-
-    public SM4_Context()
-    {
-        this.mode = 1;
-        this.isPadding = true;
-        this.sk = new long[32];
-    }
-}

+ 0 - 154
Admin.NET/Admin.NET.Core/Util/SM/SM4Util.cs

@@ -1,154 +0,0 @@
-// 麻省理工学院许可证
-//
-// 版权所有 (c) 2021-2023 zuohuaijun,大名科技(天津)有限公司  联系电话/微信:18020030720  QQ:515096995
-//
-// 特此免费授予获得本软件的任何人以处理本软件的权利,但须遵守以下条件:在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
-//
-// 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
-// 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
-
-using Org.BouncyCastle.Utilities.Encoders;
-
-namespace Admin.NET.Core;
-
-/// <summary>
-/// SM4工具类
-/// </summary>
-public class SM4Util
-{
-    public string secretKey = "1814546261730461"; // 长度必须为16字节
-    public string iv = "0000000000000000";
-    public bool hexString = false;
-    public bool forJavascript = false;
-
-    public string Encrypt_ECB(string plainText)
-    {
-        var ctx = new SM4_Context
-        {
-            isPadding = true,
-            mode = SM4.SM4_ENCRYPT
-        };
-
-        byte[] keyBytes;
-        if (hexString)
-        {
-            keyBytes = Hex.Decode(secretKey);
-        }
-        else
-        {
-            keyBytes = Encoding.ASCII.GetBytes(secretKey);
-        }
-
-        var sm4 = new SM4();
-        sm4.FOR_JAVASCRIPT = forJavascript;
-
-        sm4.Sm4_setkey_enc(ctx, keyBytes);
-        byte[] encrypted = sm4.Sm4_crypt_ecb(ctx, Encoding.ASCII.GetBytes(plainText));
-
-        string cipherText = Encoding.ASCII.GetString(Hex.Encode(encrypted));
-        return cipherText;
-    }
-
-    public byte[] Encrypt_ECB(byte[] plainBytes, byte[] keyBytes)
-    {
-        var ctx = new SM4_Context
-        {
-            isPadding = false,
-            mode = SM4.SM4_ENCRYPT
-        };
-
-        var sm4 = new SM4();
-
-        sm4.FOR_JAVASCRIPT = forJavascript;
-
-        sm4.Sm4_setkey_enc(ctx, keyBytes);
-        byte[] encrypted = sm4.Sm4_crypt_ecb(ctx, plainBytes);
-        return encrypted;
-
-        //return Hex.Encode(encrypted);
-    }
-
-    public string Decrypt_ECB(string cipherText)
-    {
-        var ctx = new SM4_Context
-        {
-            isPadding = true,
-            mode = SM4.SM4_DECRYPT
-        };
-
-        byte[] keyBytes;
-        if (hexString)
-        {
-            keyBytes = Hex.Decode(secretKey);
-        }
-        else
-        {
-            keyBytes = Encoding.ASCII.GetBytes(secretKey);
-        }
-
-        var sm4 = new SM4();
-        sm4.FOR_JAVASCRIPT = forJavascript;
-
-        sm4.Sm4_setkey_dec(ctx, keyBytes);
-        byte[] decrypted = sm4.Sm4_crypt_ecb(ctx, Hex.Decode(cipherText));
-        return Encoding.ASCII.GetString(decrypted);
-    }
-
-    public string Encrypt_CBC(string plainText)
-    {
-        var ctx = new SM4_Context
-        {
-            isPadding = true,
-            mode = SM4.SM4_ENCRYPT
-        };
-
-        byte[] keyBytes;
-        byte[] ivBytes;
-        if (hexString)
-        {
-            keyBytes = Hex.Decode(secretKey);
-            ivBytes = Hex.Decode(iv);
-        }
-        else
-        {
-            keyBytes = Encoding.ASCII.GetBytes(secretKey);
-            ivBytes = Encoding.ASCII.GetBytes(iv);
-        }
-
-        var sm4 = new SM4();
-        sm4.FOR_JAVASCRIPT = forJavascript;
-        sm4.Sm4_setkey_enc(ctx, keyBytes);
-        byte[] encrypted = sm4.Sm4_crypt_cbc(ctx, ivBytes, Encoding.ASCII.GetBytes(plainText));
-
-        string cipherText = Encoding.ASCII.GetString(Hex.Encode(encrypted));
-        return cipherText;
-    }
-
-    public string Decrypt_CBC(string cipherText)
-    {
-        var ctx = new SM4_Context
-        {
-            isPadding = true,
-            mode = SM4.SM4_DECRYPT
-        };
-
-        byte[] keyBytes;
-        byte[] ivBytes;
-        if (hexString)
-        {
-            keyBytes = Hex.Decode(secretKey);
-            ivBytes = Hex.Decode(iv);
-        }
-        else
-        {
-            keyBytes = Encoding.ASCII.GetBytes(secretKey);
-            ivBytes = Encoding.ASCII.GetBytes(iv);
-        }
-
-        var sm4 = new SM4();
-        sm4.FOR_JAVASCRIPT = forJavascript;
-        sm4.Sm4_setkey_dec(ctx, keyBytes);
-        byte[] decrypted = sm4.Sm4_crypt_cbc(ctx, ivBytes, Hex.Decode(cipherText));
-        return Encoding.ASCII.GetString(decrypted);
-    }
-}

+ 0 - 23
Admin.NET/Admin.NET.Core/Util/SM/SMUtil.cs

@@ -1,23 +0,0 @@
-// 麻省理工学院许可证
-//
-// 版权所有 (c) 2021-2023 zuohuaijun,大名科技(天津)有限公司  联系电话/微信:18020030720  QQ:515096995
-//
-// 特此免费授予获得本软件的任何人以处理本软件的权利,但须遵守以下条件:在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
-//
-// 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
-// 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
-
-using Org.BouncyCastle.Utilities.Encoders;
-
-namespace Admin.NET.Core;
-
-/// <summary>
-/// SM工具类
-/// </summary>
-public class SMUtil
-{
-    public static string StrToHex(string str)
-    {
-        return Encoding.ASCII.GetString(Hex.Encode(Encoding.UTF8.GetBytes(str))).ToUpper();
-    }
-}

+ 1 - 0
Web/package.json

@@ -38,6 +38,7 @@
 		"qrcodejs2-fixes": "^0.0.2",
 		"qs": "^6.11.2",
 		"screenfull": "^6.0.2",
+		"sm-crypto-v2": "^1.7.0",
 		"sortablejs": "^1.15.0",
 		"splitpanes": "^3.1.5",
 		"vcrontab-3": "^3.3.22",

+ 20 - 0
Web/pnpm-lock.yaml

@@ -86,6 +86,9 @@ dependencies:
   screenfull:
     specifier: ^6.0.2
     version: 6.0.2
+  sm-crypto-v2:
+    specifier: ^1.7.0
+    version: 1.7.0
   sortablejs:
     specifier: ^1.15.0
     version: 1.15.0
@@ -1015,6 +1018,17 @@ packages:
       - utf-8-validate
     dev: false
 
+  /@noble/curves@1.2.0:
+    resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==}
+    dependencies:
+      '@noble/hashes': 1.3.2
+    dev: false
+
+  /@noble/hashes@1.3.2:
+    resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==}
+    engines: {node: '>= 16'}
+    dev: false
+
   /@nodelib/fs.scandir@2.1.5:
     resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
     engines: {node: '>= 8'}
@@ -3683,6 +3697,12 @@ packages:
       tiny-warning: 1.0.3
     dev: false
 
+  /sm-crypto-v2@1.7.0:
+    resolution: {integrity: sha512-dKLXSDHRbMl2mgmKQ+6ijYDm7hAAbtjihuS3YcwA7K/o1phxaUVL2kvHR9AtCmlMQwEn6sD6/cdF8verBTj6Gw==}
+    dependencies:
+      '@noble/curves': 1.2.0
+    dev: false
+
   /snabbdom@3.5.1:
     resolution: {integrity: sha512-wHMNIOjkm/YNE5EM3RCbr/+DVgPg6AqQAX1eOxO46zYNvCXjKP5Y865tqQj3EXnaMBjkxmQA5jFuDpDK/dbfiA==}
     engines: {node: '>=8.3.0'}

+ 6 - 0
Web/src/views/login/component/account.vue

@@ -81,6 +81,7 @@ import { initBackEndControlRoutes } from '/@/router/backEnd';
 import { Local, Session } from '/@/utils/storage';
 import { formatAxis } from '/@/utils/formatTime';
 import { NextLoading } from '/@/utils/loading';
+import { sm2 } from 'sm-crypto-v2';
 
 import { accessTokenKey, clearTokens, feature, getAPI } from '/@/utils/axios-utils';
 import { SysAuthApi } from '/@/api-services/api';
@@ -157,6 +158,11 @@ const onSignIn = async () => {
 		try {
 			state.loading.signIn = true;
 
+			// SM2加密密码
+			// const keys = SM2.generateKeyPair();
+			const publicKey = `0484c7466d950e120e5ece5dd85d0c90eaa85081a3a2bd7c57ae6dc822efccbd66620c67b0103fc8dd280e36c3b282977b722aaec3c56518edcebafb72c5a05312`;
+			state.ruleForm.password = sm2.doEncrypt(state.ruleForm.password, publicKey, 1);
+
 			const [err, res] = await feature(getAPI(SysAuthApi).apiSysAuthLoginPost(state.ruleForm));
 			if (err) {
 				getCaptcha(); // 重新获取验证码