Просмотр исходного кода

Merge remote-tracking branch 'upstream/next' into next

orzMaster 2 лет назад
Родитель
Сommit
38b14d8fd8
30 измененных файлов с 1366 добавлено и 1483 удалено
  1. 2 2
      Admin.NET/Admin.NET.Application/Configuration/App.json
  2. 7 7
      Admin.NET/Admin.NET.Core/Logging/LoggingSetup.cs
  3. 6 6
      Admin.NET/Admin.NET.Core/SeedData/SysUserSeedData.cs
  4. 3 0
      Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs
  5. 11 0
      Admin.NET/Admin.NET.Core/Service/Print/SysPrintService.cs
  6. 1 1
      Admin.NET/Admin.NET.Core/Service/Tenant/SysTenantService.cs
  7. 16 11
      Admin.NET/Admin.NET.Core/Service/User/Dto/UserOutput.cs
  8. 11 1
      Admin.NET/Admin.NET.Core/Service/User/SysUserService.cs
  9. 6 13
      Admin.NET/Admin.NET.Core/Util/CryptogramUtil.cs
  10. 472 0
      Admin.NET/Admin.NET.Core/Util/GM/GM.cs
  11. 119 0
      Admin.NET/Admin.NET.Core/Util/GM/GMUtil.cs
  12. 0 139
      Admin.NET/Admin.NET.Core/Util/SM/Cipher.cs
  13. 0 119
      Admin.NET/Admin.NET.Core/Util/SM/SM2.cs
  14. 0 176
      Admin.NET/Admin.NET.Core/Util/SM/SM2Util.cs
  15. 0 408
      Admin.NET/Admin.NET.Core/Util/SM/SM3.cs
  16. 0 37
      Admin.NET/Admin.NET.Core/Util/SM/SM3Util.cs
  17. 0 345
      Admin.NET/Admin.NET.Core/Util/SM/SM4.cs
  18. 0 154
      Admin.NET/Admin.NET.Core/Util/SM/SM4Util.cs
  19. 1 0
      Web/package.json
  20. 20 0
      Web/pnpm-lock.yaml
  21. 85 0
      Web/src/api-services/apis/sys-print-api.ts
  22. 4 4
      Web/src/api-services/apis/sys-user-api.ts
  23. 73 0
      Web/src/api-services/models/admin-result-sql-sugar-paged-list-user-output.ts
  24. 12 12
      Web/src/api-services/models/admin-result-sys-print.ts
  25. 4 2
      Web/src/api-services/models/index.ts
  26. 13 13
      Web/src/api-services/models/sql-sugar-paged-list-user-output.ts
  27. 458 0
      Web/src/api-services/models/user-output.ts
  28. 6 0
      Web/src/views/login/component/account.vue
  29. 28 28
      Web/src/views/system/user/component/editUser.vue
  30. 8 5
      Web/src/views/system/user/index.vue

+ 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" // 私钥
   }
 }

+ 7 - 7
Admin.NET/Admin.NET.Core/Logging/LoggingSetup.cs

@@ -17,13 +17,13 @@ public static class LoggingSetup
     /// <param name="services"></param>
     public static void AddLoggingSetup(this IServiceCollection services)
     {
-        //// 控制台日志格式化
-        //services.AddConsoleFormatter(options =>
-        //{
-        //    options.DateFormat = "yyyy-MM-dd HH:mm:ss(zzz) dddd";
-        //    //options.WithTraceId = true; // 显示线程Id
-        //    //options.WithStackFrame = true; // 显示程序集
-        //});
+        // 控制台日志格式化
+        services.AddConsoleFormatter(options =>
+        {
+            options.DateFormat = "yyyy-MM-dd HH:mm:ss(zzz) dddd";
+            //options.WithTraceId = true; // 显示线程Id
+            //options.WithStackFrame = true; // 显示程序集
+        });
 
         // 日志监听
         services.AddMonitorLogging(options =>

+ 6 - 6
Admin.NET/Admin.NET.Core/SeedData/SysUserSeedData.cs

@@ -24,12 +24,12 @@ public class SysUserSeedData : ISqlSugarEntitySeedData<SysUser>
 
         return new[]
         {
-            new SysUser{ Id=1300000000101, Account="superadmin", Password=encryptPasswod, NickName="超级管理员", RealName="超级管理员", Phone="18020030720", Birthday=DateTime.Parse("1986-06-28"), Sex=GenderEnum.Male, AccountType=AccountTypeEnum.SuperAdmin, Remark="超级管理员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), TenantId=1300000000001 },
-            new SysUser{ Id=1300000000111, Account="admin", Password=encryptPasswod, NickName="系统管理员", RealName="系统管理员", Phone="18020030720", Birthday=DateTime.Parse("1986-06-28"), Sex=GenderEnum.Male, AccountType=AccountTypeEnum.SysAdmin, Remark="系统管理员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=1300000000101, PosId=1300000000102, TenantId=1300000000001 },
-            new SysUser{ Id=1300000000112, Account="user1", Password=encryptPasswod, NickName="部门主管", RealName="部门主管", Phone="18020030720", Birthday=DateTime.Parse("1986-06-28"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.NormalUser, Remark="部门主管", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=1300000000102, PosId=1300000000108, TenantId=1300000000001 },
-            new SysUser{ Id=1300000000113, Account="user2", Password=encryptPasswod, NickName="部门职员", RealName="部门职员", Phone="18020030720", Birthday=DateTime.Parse("1986-06-28"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.NormalUser, Remark="部门职员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=1300000000103, PosId=1300000000110, TenantId=1300000000001 },
-            new SysUser{ Id=1300000000114, Account="user3", Password=encryptPasswod, NickName="普通用户", RealName="普通用户", Phone="18020030720", Birthday=DateTime.Parse("1986-06-28"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.NormalUser, Remark="普通用户", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=1300000000104, PosId=1300000000115, TenantId=1300000000001 },
-            new SysUser{ Id=1300000000115, Account="user4", Password=encryptPasswod, NickName="其他", RealName="其他", Phone="18020030720", Birthday=DateTime.Parse("1986-06-28"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.Member, Remark="会员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=1300000000105, PosId=1300000000116, TenantId=1300000000001 },
+            new SysUser{ Id=1300000000101, Account="superadmin", Password=encryptPasswod, NickName="超级管理员", RealName="超级管理员", Phone="18020030720", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Male, AccountType=AccountTypeEnum.SuperAdmin, Remark="超级管理员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), TenantId=1300000000001 },
+            new SysUser{ Id=1300000000111, Account="admin", Password=encryptPasswod, NickName="系统管理员", RealName="系统管理员", Phone="18020030720", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Male, AccountType=AccountTypeEnum.SysAdmin, Remark="系统管理员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=1300000000101, PosId=1300000000102, TenantId=1300000000001 },
+            new SysUser{ Id=1300000000112, Account="user1", Password=encryptPasswod, NickName="部门主管", RealName="部门主管", Phone="18020030720", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.NormalUser, Remark="部门主管", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=1300000000102, PosId=1300000000108, TenantId=1300000000001 },
+            new SysUser{ Id=1300000000113, Account="user2", Password=encryptPasswod, NickName="部门职员", RealName="部门职员", Phone="18020030720", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.NormalUser, Remark="部门职员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=1300000000103, PosId=1300000000110, TenantId=1300000000001 },
+            new SysUser{ Id=1300000000114, Account="user3", Password=encryptPasswod, NickName="普通用户", RealName="普通用户", Phone="18020030720", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.NormalUser, Remark="普通用户", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=1300000000104, PosId=1300000000115, TenantId=1300000000001 },
+            new SysUser{ Id=1300000000115, Account="user4", Password=encryptPasswod, NickName="其他", RealName="其他", Phone="18020030720", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.Member, Remark="会员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=1300000000105, PosId=1300000000116, TenantId=1300000000001 },
         };
     }
 }

+ 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())
         {

+ 11 - 0
Admin.NET/Admin.NET.Core/Service/Print/SysPrintService.cs

@@ -36,6 +36,17 @@ public class SysPrintService : IDynamicApiController, ITransient
             .ToPagedListAsync(input.Page, input.PageSize);
     }
 
+    /// <summary>
+    /// 获取打印模板
+    /// </summary>
+    /// <param name="name"></param>
+    /// <returns></returns>
+    [DisplayName("获取打印模板")]
+    public async Task<SysPrint> GetPrint(string name)
+    {
+        return await _sysPrintRep.GetFirstAsync(u => u.Name == name);
+    }
+
     /// <summary>
     /// 增加打印模板
     /// </summary>

+ 1 - 1
Admin.NET/Admin.NET.Core/Service/Tenant/SysTenantService.cs

@@ -202,7 +202,7 @@ public class SysTenantService : IDynamicApiController, ITransient
             AccountType = AccountTypeEnum.SysAdmin,
             OrgId = newOrg.Id,
             PosId = newPos.Id,
-            Birthday = DateTime.Parse("1986-06-28"),
+            Birthday = DateTime.Parse("2000-01-01"),
             RealName = "租管",
             Remark = "租管" + tenantName,
         };

+ 16 - 11
Admin.NET/Admin.NET.Core/Util/SM/SMUtil.cs → Admin.NET/Admin.NET.Core/Service/User/Dto/UserOutput.cs

@@ -7,17 +7,22 @@
 // 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
 // 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
 
-using Org.BouncyCastle.Utilities.Encoders;
+namespace Admin.NET.Core.Service;
 
-namespace Admin.NET.Core;
-
-/// <summary>
-/// SM工具类
-/// </summary>
-public class SMUtil
+public class UserOutput : SysUser
 {
-    public static string StrToHex(string str)
-    {
-        return Encoding.ASCII.GetString(Hex.Encode(Encoding.UTF8.GetBytes(str))).ToUpper();
-    }
+    /// <summary>
+    /// 机构名称
+    /// </summary>
+    public string OrgName { get; set; }
+
+    /// <summary>
+    /// 职位名称
+    /// </summary>
+    public string PosName { get; set; }
+
+    /// <summary>
+    /// 角色名称
+    /// </summary>
+    public string RoleName { get; set; }
 }

+ 11 - 1
Admin.NET/Admin.NET.Core/Service/User/SysUserService.cs

@@ -43,7 +43,7 @@ public class SysUserService : IDynamicApiController, ITransient
     /// <param name="input"></param>
     /// <returns></returns>
     [DisplayName("获取用户分页列表")]
-    public async Task<SqlSugarPagedList<SysUser>> Page(PageUserInput input)
+    public async Task<SqlSugarPagedList<UserOutput>> Page(PageUserInput input)
     {
         // 获取用户拥有的机构集合
         var userOrgIdList = await _sysOrgService.GetUserOrgIdList();
@@ -59,12 +59,22 @@ public class SysUserService : IDynamicApiController, ITransient
         }
 
         return await _sysUserRep.AsQueryable()
+            .LeftJoin<SysOrg>((u, a) => u.OrgId == a.Id)
+            .LeftJoin<SysPos>((u, a, b) => u.PosId == b.Id)
+            .LeftJoin<SysUserRole>((u, a, b, c) => u.Id == c.UserId)
+            .LeftJoin<SysRole>((u, a, b, c, d) => c.RoleId == d.Id)
             .Where(u => u.AccountType != AccountTypeEnum.SuperAdmin)
             .WhereIF(orgList != null, u => orgList.Contains(u.OrgId))
             .WhereIF(!string.IsNullOrWhiteSpace(input.Account), u => u.Account.Contains(input.Account))
             .WhereIF(!string.IsNullOrWhiteSpace(input.RealName), u => u.RealName.Contains(input.RealName))
             .WhereIF(!string.IsNullOrWhiteSpace(input.Phone), u => u.Phone.Contains(input.Phone))
             .OrderBy(u => u.OrderNo)
+            .Select((u, a, b, c, d) => new UserOutput
+            {
+                OrgName = a.Name,
+                PosName = b.Name,
+                RoleName = d.Name
+            }, true)
             .ToPagedListAsync(input.Page, input.PageSize);
     }
 

+ 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);
-    }
-}

+ 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'}

+ 85 - 0
Web/src/api-services/apis/sys-print-api.ts

@@ -19,6 +19,7 @@ import { Configuration } from '../configuration';
 import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base';
 import { AddPrintInput } from '../models';
 import { AdminResultSqlSugarPagedListSysPrint } from '../models';
+import { AdminResultSysPrint } from '../models';
 import { DeletePrintInput } from '../models';
 import { PagePrintInput } from '../models';
 import { UpdatePrintInput } from '../models';
@@ -172,6 +173,55 @@ export const SysPrintApiAxiosParamCreator = function (configuration?: Configurat
                 options: localVarRequestOptions,
             };
         },
+        /**
+         * 
+         * @summary 获取打印模板
+         * @param {string} name 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysPrintPrintNameGet: async (name: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            // verify required parameter 'name' is not null or undefined
+            if (name === null || name === undefined) {
+                throw new RequiredError('name','Required parameter name was null or undefined when calling apiSysPrintPrintNameGet.');
+            }
+            const localVarPath = `/api/sysPrint/print/{name}`
+                .replace(`{${"name"}}`, encodeURIComponent(String(name)));
+            // use dummy base URL string because the URL constructor only accepts absolute URLs.
+            const localVarUrlObj = new URL(localVarPath, 'https://example.com');
+            let baseOptions;
+            if (configuration) {
+                baseOptions = configuration.baseOptions;
+            }
+            const localVarRequestOptions :AxiosRequestConfig = { method: 'GET', ...baseOptions, ...options};
+            const localVarHeaderParameter = {} as any;
+            const localVarQueryParameter = {} as any;
+
+            // authentication Bearer required
+            // http bearer authentication required
+            if (configuration && configuration.accessToken) {
+                const accessToken = typeof configuration.accessToken === 'function'
+                    ? await configuration.accessToken()
+                    : await configuration.accessToken;
+                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
+            }
+
+            const query = new URLSearchParams(localVarUrlObj.search);
+            for (const key in localVarQueryParameter) {
+                query.set(key, localVarQueryParameter[key]);
+            }
+            for (const key in options.params) {
+                query.set(key, options.params[key]);
+            }
+            localVarUrlObj.search = (new URLSearchParams(query)).toString();
+            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
+            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+
+            return {
+                url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
+                options: localVarRequestOptions,
+            };
+        },
         /**
          * 
          * @summary 更新打印模板
@@ -271,6 +321,20 @@ export const SysPrintApiFp = function(configuration?: Configuration) {
                 return axios.request(axiosRequestArgs);
             };
         },
+        /**
+         * 
+         * @summary 获取打印模板
+         * @param {string} name 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysPrintPrintNameGet(name: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultSysPrint>>> {
+            const localVarAxiosArgs = await SysPrintApiAxiosParamCreator(configuration).apiSysPrintPrintNameGet(name, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
         /**
          * 
          * @summary 更新打印模板
@@ -324,6 +388,16 @@ export const SysPrintApiFactory = function (configuration?: Configuration, baseP
         async apiSysPrintPagePost(body?: PagePrintInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultSqlSugarPagedListSysPrint>> {
             return SysPrintApiFp(configuration).apiSysPrintPagePost(body, options).then((request) => request(axios, basePath));
         },
+        /**
+         * 
+         * @summary 获取打印模板
+         * @param {string} name 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysPrintPrintNameGet(name: string, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultSysPrint>> {
+            return SysPrintApiFp(configuration).apiSysPrintPrintNameGet(name, options).then((request) => request(axios, basePath));
+        },
         /**
          * 
          * @summary 更新打印模板
@@ -377,6 +451,17 @@ export class SysPrintApi extends BaseAPI {
     public async apiSysPrintPagePost(body?: PagePrintInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultSqlSugarPagedListSysPrint>> {
         return SysPrintApiFp(this.configuration).apiSysPrintPagePost(body, options).then((request) => request(this.axios, this.basePath));
     }
+    /**
+     * 
+     * @summary 获取打印模板
+     * @param {string} name 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysPrintApi
+     */
+    public async apiSysPrintPrintNameGet(name: string, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultSysPrint>> {
+        return SysPrintApiFp(this.configuration).apiSysPrintPrintNameGet(name, options).then((request) => request(this.axios, this.basePath));
+    }
     /**
      * 
      * @summary 更新打印模板

+ 4 - 4
Web/src/api-services/apis/sys-user-api.ts

@@ -22,7 +22,7 @@ import { AdminResultInt32 } from '../models';
 import { AdminResultInt64 } from '../models';
 import { AdminResultListInt64 } from '../models';
 import { AdminResultListSysUserExtOrg } from '../models';
-import { AdminResultSqlSugarPagedListSysUser } from '../models';
+import { AdminResultSqlSugarPagedListUserOutput } from '../models';
 import { AdminResultString } from '../models';
 import { AdminResultSysUser } from '../models';
 import { ChangePwdInput } from '../models';
@@ -739,7 +739,7 @@ export const SysUserApiFp = function(configuration?: Configuration) {
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
          */
-        async apiSysUserPagePost(body?: PageUserInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultSqlSugarPagedListSysUser>>> {
+        async apiSysUserPagePost(body?: PageUserInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultSqlSugarPagedListUserOutput>>> {
             const localVarAxiosArgs = await SysUserApiAxiosParamCreator(configuration).apiSysUserPagePost(body, options);
             return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
                 const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
@@ -883,7 +883,7 @@ export const SysUserApiFactory = function (configuration?: Configuration, basePa
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
          */
-        async apiSysUserPagePost(body?: PageUserInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultSqlSugarPagedListSysUser>> {
+        async apiSysUserPagePost(body?: PageUserInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultSqlSugarPagedListUserOutput>> {
             return SysUserApiFp(configuration).apiSysUserPagePost(body, options).then((request) => request(axios, basePath));
         },
         /**
@@ -1021,7 +1021,7 @@ export class SysUserApi extends BaseAPI {
      * @throws {RequiredError}
      * @memberof SysUserApi
      */
-    public async apiSysUserPagePost(body?: PageUserInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultSqlSugarPagedListSysUser>> {
+    public async apiSysUserPagePost(body?: PageUserInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultSqlSugarPagedListUserOutput>> {
         return SysUserApiFp(this.configuration).apiSysUserPagePost(body, options).then((request) => request(this.axios, this.basePath));
     }
     /**

+ 73 - 0
Web/src/api-services/models/admin-result-sql-sugar-paged-list-user-output.ts

@@ -0,0 +1,73 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+import { SqlSugarPagedListUserOutput } from './sql-sugar-paged-list-user-output';
+import {
+    SqlSugarPagedListUserOutput,
+} from ".";
+
+/**
+ * 全局返回结果
+ *
+ * @export
+ * @interface AdminResultSqlSugarPagedListUserOutput
+ */
+export interface AdminResultSqlSugarPagedListUserOutput {
+
+    /**
+     * 状态码
+     *
+     * @type {number}
+     * @memberof AdminResultSqlSugarPagedListUserOutput
+     */
+    code?: number;
+
+    /**
+     * 类型success、warning、error
+     *
+     * @type {string}
+     * @memberof AdminResultSqlSugarPagedListUserOutput
+     */
+    type?: string | null;
+
+    /**
+     * 错误信息
+     *
+     * @type {string}
+     * @memberof AdminResultSqlSugarPagedListUserOutput
+     */
+    message?: string | null;
+
+    /**
+     * @type {SqlSugarPagedListUserOutput}
+     * @memberof AdminResultSqlSugarPagedListUserOutput
+     */
+    result?: SqlSugarPagedListUserOutput;
+
+    /**
+     * 附加数据
+     *
+     * @type {any}
+     * @memberof AdminResultSqlSugarPagedListUserOutput
+     */
+    extras?: any | null;
+
+    /**
+     * 时间
+     *
+     * @type {Date}
+     * @memberof AdminResultSqlSugarPagedListUserOutput
+     */
+    time?: Date;
+}

+ 12 - 12
Web/src/api-services/models/admin-result-sql-sugar-paged-list-sys-user.ts → Web/src/api-services/models/admin-result-sys-print.ts

@@ -12,24 +12,24 @@
  * Do not edit the class manually.
  */
 
-import { SqlSugarPagedListSysUser } from './sql-sugar-paged-list-sys-user';
+import { SysPrint } from './sys-print';
 import {
-    SqlSugarPagedListSysUser,
+    SysPrint,
 } from ".";
 
 /**
  * 全局返回结果
  *
  * @export
- * @interface AdminResultSqlSugarPagedListSysUser
+ * @interface AdminResultSysPrint
  */
-export interface AdminResultSqlSugarPagedListSysUser {
+export interface AdminResultSysPrint {
 
     /**
      * 状态码
      *
      * @type {number}
-     * @memberof AdminResultSqlSugarPagedListSysUser
+     * @memberof AdminResultSysPrint
      */
     code?: number;
 
@@ -37,7 +37,7 @@ export interface AdminResultSqlSugarPagedListSysUser {
      * 类型success、warning、error
      *
      * @type {string}
-     * @memberof AdminResultSqlSugarPagedListSysUser
+     * @memberof AdminResultSysPrint
      */
     type?: string | null;
 
@@ -45,21 +45,21 @@ export interface AdminResultSqlSugarPagedListSysUser {
      * 错误信息
      *
      * @type {string}
-     * @memberof AdminResultSqlSugarPagedListSysUser
+     * @memberof AdminResultSysPrint
      */
     message?: string | null;
 
     /**
-     * @type {SqlSugarPagedListSysUser}
-     * @memberof AdminResultSqlSugarPagedListSysUser
+     * @type {SysPrint}
+     * @memberof AdminResultSysPrint
      */
-    result?: SqlSugarPagedListSysUser;
+    result?: SysPrint;
 
     /**
      * 附加数据
      *
      * @type {any}
-     * @memberof AdminResultSqlSugarPagedListSysUser
+     * @memberof AdminResultSysPrint
      */
     extras?: any | null;
 
@@ -67,7 +67,7 @@ export interface AdminResultSqlSugarPagedListSysUser {
      * 时间
      *
      * @type {Date}
-     * @memberof AdminResultSqlSugarPagedListSysUser
+     * @memberof AdminResultSysPrint
      */
     time?: Date;
 }

+ 4 - 2
Web/src/api-services/models/index.ts

@@ -70,15 +70,16 @@ export * from './admin-result-sql-sugar-paged-list-sys-plugin';
 export * from './admin-result-sql-sugar-paged-list-sys-print';
 export * from './admin-result-sql-sugar-paged-list-sys-region';
 export * from './admin-result-sql-sugar-paged-list-sys-role';
-export * from './admin-result-sql-sugar-paged-list-sys-user';
 export * from './admin-result-sql-sugar-paged-list-sys-wechat-user';
 export * from './admin-result-sql-sugar-paged-list-tenant-output';
+export * from './admin-result-sql-sugar-paged-list-user-output';
 export * from './admin-result-string';
 export * from './admin-result-sys-code-gen';
 export * from './admin-result-sys-code-gen-config';
 export * from './admin-result-sys-config';
 export * from './admin-result-sys-dict-data';
 export * from './admin-result-sys-dict-type';
+export * from './admin-result-sys-print';
 export * from './admin-result-sys-user';
 export * from './admin-result-sys-wechat-pay';
 export * from './admin-result-wechat-pay-output';
@@ -196,9 +197,9 @@ export * from './sql-sugar-paged-list-sys-plugin';
 export * from './sql-sugar-paged-list-sys-print';
 export * from './sql-sugar-paged-list-sys-region';
 export * from './sql-sugar-paged-list-sys-role';
-export * from './sql-sugar-paged-list-sys-user';
 export * from './sql-sugar-paged-list-sys-wechat-user';
 export * from './sql-sugar-paged-list-tenant-output';
+export * from './sql-sugar-paged-list-user-output';
 export * from './status-enum';
 export * from './swagger-submit-url-body';
 export * from './sys-code-gen';
@@ -262,6 +263,7 @@ export * from './update-tenant-input';
 export * from './update-user-input';
 export * from './upload-file-from-base64-input';
 export * from './user-input';
+export * from './user-output';
 export * from './user-role-input';
 export * from './wechat-pay-output';
 export * from './wechat-pay-para-input';

+ 13 - 13
Web/src/api-services/models/sql-sugar-paged-list-sys-user.ts → Web/src/api-services/models/sql-sugar-paged-list-user-output.ts

@@ -12,24 +12,24 @@
  * Do not edit the class manually.
  */
 
-import { SysUser } from './sys-user';
+import { UserOutput } from './user-output';
 import {
-    SysUser,
+    UserOutput,
 } from ".";
 
 /**
  * 分页泛型集合
  *
  * @export
- * @interface SqlSugarPagedListSysUser
+ * @interface SqlSugarPagedListUserOutput
  */
-export interface SqlSugarPagedListSysUser {
+export interface SqlSugarPagedListUserOutput {
 
     /**
      * 页码
      *
      * @type {number}
-     * @memberof SqlSugarPagedListSysUser
+     * @memberof SqlSugarPagedListUserOutput
      */
     page?: number;
 
@@ -37,7 +37,7 @@ export interface SqlSugarPagedListSysUser {
      * 页容量
      *
      * @type {number}
-     * @memberof SqlSugarPagedListSysUser
+     * @memberof SqlSugarPagedListUserOutput
      */
     pageSize?: number;
 
@@ -45,7 +45,7 @@ export interface SqlSugarPagedListSysUser {
      * 总条数
      *
      * @type {number}
-     * @memberof SqlSugarPagedListSysUser
+     * @memberof SqlSugarPagedListUserOutput
      */
     total?: number;
 
@@ -53,23 +53,23 @@ export interface SqlSugarPagedListSysUser {
      * 总页数
      *
      * @type {number}
-     * @memberof SqlSugarPagedListSysUser
+     * @memberof SqlSugarPagedListUserOutput
      */
     totalPages?: number;
 
     /**
      * 当前页集合
      *
-     * @type {Array<SysUser>}
-     * @memberof SqlSugarPagedListSysUser
+     * @type {Array<UserOutput>}
+     * @memberof SqlSugarPagedListUserOutput
      */
-    items?: Array<SysUser> | null;
+    items?: Array<UserOutput> | null;
 
     /**
      * 是否有上一页
      *
      * @type {boolean}
-     * @memberof SqlSugarPagedListSysUser
+     * @memberof SqlSugarPagedListUserOutput
      */
     hasPrevPage?: boolean;
 
@@ -77,7 +77,7 @@ export interface SqlSugarPagedListSysUser {
      * 是否有下一页
      *
      * @type {boolean}
-     * @memberof SqlSugarPagedListSysUser
+     * @memberof SqlSugarPagedListUserOutput
      */
     hasNextPage?: boolean;
 }

+ 458 - 0
Web/src/api-services/models/user-output.ts

@@ -0,0 +1,458 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+import { AccountTypeEnum } from './account-type-enum';
+import { CardTypeEnum } from './card-type-enum';
+import { CultureLevelEnum } from './culture-level-enum';
+import { GenderEnum } from './gender-enum';
+import { StatusEnum } from './status-enum';
+import { SysOrg } from './sys-org';
+import { SysPos } from './sys-pos';
+import { SysUser } from './sys-user';
+import {
+    AccountTypeEnum,CardTypeEnum,CultureLevelEnum,GenderEnum,StatusEnum,SysOrg,SysPos,SysUser,
+} from ".";
+
+/**
+ * 
+ *
+ * @export
+ * @interface UserOutput
+ */
+export interface UserOutput {
+
+    /**
+     * 雪花Id
+     *
+     * @type {number}
+     * @memberof UserOutput
+     */
+    id?: number;
+
+    /**
+     * 创建时间
+     *
+     * @type {Date}
+     * @memberof UserOutput
+     */
+    createTime?: Date | null;
+
+    /**
+     * 更新时间
+     *
+     * @type {Date}
+     * @memberof UserOutput
+     */
+    updateTime?: Date | null;
+
+    /**
+     * 创建者Id
+     *
+     * @type {number}
+     * @memberof UserOutput
+     */
+    createUserId?: number | null;
+
+    /**
+     * 创建者姓名
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    createUserName?: string | null;
+
+    /**
+     * 修改者Id
+     *
+     * @type {number}
+     * @memberof UserOutput
+     */
+    updateUserId?: number | null;
+
+    /**
+     * 修改者姓名
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    updateUserName?: string | null;
+
+    /**
+     * 软删除
+     *
+     * @type {boolean}
+     * @memberof UserOutput
+     */
+    isDelete?: boolean;
+
+    /**
+     * 租户Id
+     *
+     * @type {number}
+     * @memberof UserOutput
+     */
+    tenantId?: number | null;
+
+    /**
+     * 账号
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    account: string;
+
+    /**
+     * 真实姓名
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    realName?: string | null;
+
+    /**
+     * 昵称
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    nickName?: string | null;
+
+    /**
+     * 头像
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    avatar?: string | null;
+
+    /**
+     * @type {GenderEnum}
+     * @memberof UserOutput
+     */
+    sex?: GenderEnum;
+
+    /**
+     * 年龄
+     *
+     * @type {number}
+     * @memberof UserOutput
+     */
+    age?: number;
+
+    /**
+     * 出生日期
+     *
+     * @type {Date}
+     * @memberof UserOutput
+     */
+    birthday?: Date | null;
+
+    /**
+     * 民族
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    nation?: string | null;
+
+    /**
+     * 手机号码
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    phone?: string | null;
+
+    /**
+     * @type {CardTypeEnum}
+     * @memberof UserOutput
+     */
+    cardType?: CardTypeEnum;
+
+    /**
+     * 身份证号
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    idCardNum?: string | null;
+
+    /**
+     * 邮箱
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    email?: string | null;
+
+    /**
+     * 地址
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    address?: string | null;
+
+    /**
+     * @type {CultureLevelEnum}
+     * @memberof UserOutput
+     */
+    cultureLevel?: CultureLevelEnum;
+
+    /**
+     * 政治面貌
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    politicalOutlook?: string | null;
+
+    /**
+     * 毕业院校
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    college?: string | null;
+
+    /**
+     * 办公电话
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    officePhone?: string | null;
+
+    /**
+     * 紧急联系人
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    emergencyContact?: string | null;
+
+    /**
+     * 紧急联系人电话
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    emergencyPhone?: string | null;
+
+    /**
+     * 紧急联系人地址
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    emergencyAddress?: string | null;
+
+    /**
+     * 个人简介
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    introduction?: string | null;
+
+    /**
+     * 排序
+     *
+     * @type {number}
+     * @memberof UserOutput
+     */
+    orderNo?: number;
+
+    /**
+     * @type {StatusEnum}
+     * @memberof UserOutput
+     */
+    status?: StatusEnum;
+
+    /**
+     * 备注
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    remark?: string | null;
+
+    /**
+     * @type {AccountTypeEnum}
+     * @memberof UserOutput
+     */
+    accountType?: AccountTypeEnum;
+
+    /**
+     * 直属机构Id
+     *
+     * @type {number}
+     * @memberof UserOutput
+     */
+    orgId?: number;
+
+    /**
+     * @type {SysOrg}
+     * @memberof UserOutput
+     */
+    sysOrg?: SysOrg;
+
+    /**
+     * 直属主管Id
+     *
+     * @type {number}
+     * @memberof UserOutput
+     */
+    managerUserId?: number | null;
+
+    /**
+     * @type {SysUser}
+     * @memberof UserOutput
+     */
+    managerUser?: SysUser;
+
+    /**
+     * 职位Id
+     *
+     * @type {number}
+     * @memberof UserOutput
+     */
+    posId?: number;
+
+    /**
+     * @type {SysPos}
+     * @memberof UserOutput
+     */
+    sysPos?: SysPos;
+
+    /**
+     * 工号
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    jobNum?: string | null;
+
+    /**
+     * 职级
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    posLevel?: string | null;
+
+    /**
+     * 职称
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    posTitle?: string | null;
+
+    /**
+     * 擅长领域
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    expertise?: string | null;
+
+    /**
+     * 办公区域
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    officeZone?: string | null;
+
+    /**
+     * 办公室
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    office?: string | null;
+
+    /**
+     * 入职日期
+     *
+     * @type {Date}
+     * @memberof UserOutput
+     */
+    joinDate?: Date | null;
+
+    /**
+     * 最新登录Ip
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    lastLoginIp?: string | null;
+
+    /**
+     * 最新登录地点
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    lastLoginAddress?: string | null;
+
+    /**
+     * 最新登录时间
+     *
+     * @type {Date}
+     * @memberof UserOutput
+     */
+    lastLoginTime?: Date | null;
+
+    /**
+     * 最新登录设备
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    lastLoginDevice?: string | null;
+
+    /**
+     * 电子签名
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    signature?: string | null;
+
+    /**
+     * 机构名称
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    orgName?: string | null;
+
+    /**
+     * 职位名称
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    posName?: string | null;
+
+    /**
+     * 角色名称
+     *
+     * @type {string}
+     * @memberof UserOutput
+     */
+    roleName?: string | null;
+}

+ 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(); // 重新获取验证码

+ 28 - 28
Web/src/views/system/user/component/editUser.vue

@@ -8,7 +8,7 @@
 				</div>
 			</template>
 			<el-tabs v-loading="state.loading" v-model="state.selectedTabName">
-				<el-tab-pane label="基础信息">
+				<el-tab-pane label="基础信息" style="height: 550px;">
 					<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
 						<el-row :gutter="35">
 							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@@ -17,8 +17,8 @@
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
-								<el-form-item label="真实姓名" prop="realName" :rules="[{ required: true, message: '真实姓名不能为空', trigger: 'blur' }]">
-									<el-input v-model="state.ruleForm.realName" placeholder="真实姓名" clearable />
+								<el-form-item label="昵称">
+									<el-input v-model="state.ruleForm.nickName" placeholder="昵称" clearable />
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@@ -27,22 +27,8 @@
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
-								<el-form-item label="出生日期" prop="birthday" :rules="[{ required: true, message: '出生日期不能为空', trigger: 'blur' }]">
-									<el-date-picker v-model="state.ruleForm.birthday" type="date" placeholder="出生日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" class="w100" />
-								</el-form-item>
-							</el-col>
-							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
-								<el-form-item label="昵称">
-									<el-input v-model="state.ruleForm.nickName" placeholder="昵称" clearable />
-								</el-form-item>
-							</el-col>
-							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
-								<el-form-item label="性别">
-									<el-radio-group v-model="state.ruleForm.sex">
-										<el-radio :label="1">男</el-radio>
-										<el-radio :label="2">女</el-radio>
-										<el-radio :label="3">其他</el-radio>
-									</el-radio-group>
+								<el-form-item label="真实姓名" prop="realName" :rules="[{ required: true, message: '真实姓名不能为空', trigger: 'blur' }]">
+									<el-input v-model="state.ruleForm.realName" placeholder="真实姓名" clearable />
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@@ -61,9 +47,9 @@
 									</el-select>
 								</el-form-item>
 							</el-col>
-							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb5">
-								<el-form-item label="年龄">
-									<el-input-number v-model="state.ruleForm.age" placeholder="年龄" class="w100" />
+							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+								<el-form-item label="邮箱">
+									<el-input v-model="state.ruleForm.email" placeholder="邮箱" clearable />
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb5">
@@ -148,12 +134,12 @@
 										</el-col>
 									</el-row>
 								</template>
-								<el-empty :image-size="80" description="空数据" v-else></el-empty>
+								<el-empty :image-size="50" description="空数据" v-else></el-empty>
 							</el-col>
 						</el-row>
 					</el-form>
 				</el-tab-pane>
-				<el-tab-pane label="档案信息">
+				<el-tab-pane label="档案信息" style="height: 550px">
 					<el-form :model="state.ruleForm" label-width="auto">
 						<el-row :gutter="35">
 							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@@ -173,13 +159,27 @@
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
-								<el-form-item label="民族">
-									<el-input v-model="state.ruleForm.nation" placeholder="民族" clearable />
+								<el-form-item label="出生日期" prop="birthday">
+									<el-date-picker v-model="state.ruleForm.birthday" type="date" placeholder="出生日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" class="w100" />
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
-								<el-form-item label="邮箱">
-									<el-input v-model="state.ruleForm.email" placeholder="邮箱" clearable />
+								<el-form-item label="性别">
+									<el-radio-group v-model="state.ruleForm.sex">
+										<el-radio :label="1">男</el-radio>
+										<el-radio :label="2">女</el-radio>
+										<el-radio :label="3">其他</el-radio>
+									</el-radio-group>
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb5">
+								<el-form-item label="年龄">
+									<el-input-number v-model="state.ruleForm.age" placeholder="年龄" class="w100" />
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+								<el-form-item label="民族">
+									<el-input v-model="state.ruleForm.nation" placeholder="民族" clearable />
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">

+ 8 - 5
Web/src/views/system/user/index.vue

@@ -32,16 +32,16 @@
 				<el-card class="full-table" shadow="hover" style="margin-top: 8px">
 					<el-table :data="state.userData" style="width: 100%" v-loading="state.loading" border>
 						<el-table-column type="index" label="序号" width="55" align="center" fixed />
-						<el-table-column prop="account" label="账号" width="120" align="center" fixed show-overflow-tooltip />
-						<!-- <el-table-column prop="nickName" label="昵称" width="120" align="center" show-overflow-tooltip /> -->
-						<el-table-column prop="realName" label="姓名" width="120" align="center" show-overflow-tooltip />
 						<el-table-column label="头像" width="80" align="center" show-overflow-tooltip>
 							<template #default="scope">
 								<el-avatar :src="scope.row.avatar" size="small">{{ scope.row.nickName?.slice(0, 1) ?? scope.row.realName?.slice(0, 1) }} </el-avatar>
 							</template>
 						</el-table-column>
+						<el-table-column prop="account" label="账号" width="120" align="center" show-overflow-tooltip />
+						<!-- <el-table-column prop="nickName" label="昵称" width="120" align="center" show-overflow-tooltip /> -->
+						<el-table-column prop="realName" label="姓名" width="120" align="center" show-overflow-tooltip />
 						<el-table-column prop="phone" label="手机号码" width="120" align="center" show-overflow-tooltip />
-						<el-table-column label="出生日期" width="100" align="center" show-overflow-tooltip>
+						<!-- <el-table-column label="出生日期" width="100" align="center" show-overflow-tooltip>
 							<template #default="scope">
 								{{ formatDate(new Date(scope.row.birthday), 'YYYY-mm-dd') }}
 							</template>
@@ -52,7 +52,7 @@
 								<el-tag type="danger" v-else-if="scope.row.sex === 2"> 女 </el-tag>
 								<el-tag type="info" v-else> 其他 </el-tag>
 							</template>
-						</el-table-column>
+						</el-table-column> -->
 						<el-table-column label="账号类型" width="110" align="center" show-overflow-tooltip>
 							<template #default="scope">
 								<el-tag v-if="scope.row.accountType === 888"> 系统管理员 </el-tag>
@@ -61,6 +61,9 @@
 								<el-tag v-else> 其他 </el-tag>
 							</template>
 						</el-table-column>
+						<el-table-column prop="roleName" label="拥有角色" width="130" align="center" show-overflow-tooltip />
+						<el-table-column prop="orgName" label="所属机构" width="120" align="center" show-overflow-tooltip />
+						<el-table-column prop="posName" label="职位名称" width="120" align="center" show-overflow-tooltip />
 						<el-table-column label="状态" width="70" align="center" show-overflow-tooltip>
 							<template #default="scope">
 								<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="2" size="small" @change="changeStatus(scope.row)" v-auth="'sysUser:setStatus'" />