wuhb vor 4 Monaten
Ursprung
Commit
cbbd35e77c

+ 39 - 14
api/auth/login.uts

@@ -2,24 +2,33 @@
  * 登录接口
  */
 import { request } from '../../utils/request'
+import { encryptAES } from '../../utils/crypto'
+import {getStoreIsKey} from '../../utils/storage'
 
 /**
  * 账号密码登录
  * @returns 返回整个响应对象 { status, msg, success, data }
  */
-export const loginByAccount = (username: string, password: string): Promise<any> => {
-    return request({
+export const loginByAccount = async (username: string, password: string): Promise<any> => {
+    let dataForm = {
+    		username: username,
+    	    password: password
+    	};
+	
+    const isKey = getStoreIsKey();
+    if(isKey == "1"){
+    	dataForm.username = encryptAES(username);
+    	dataForm.password = encryptAES(password);
+    }
+	
+	return request({
         url: '/login',
         method: 'POST',
 		header: {
 		  isToken: false,
 		  repeatSubmit: false
 		},
-        data: {
-            username: username,
-            password: password,
-			code: 'app20251203'
-        },
+        data: dataForm,
     })
 }
 
@@ -30,18 +39,34 @@ export const getUserInfo = ():Promise<any> =>{
 	})
 }
 
-export const resetPassword = (username: string, password: string, newPassword: string): Promise<any> => {
-    return request({
+export const resetPassword = async (username: string, password: string, newPassword: string): Promise<any> => {
+	let dataForm = {
+			username: username,
+		    newPassword: newPassword,
+		    password: password
+		};
+		
+	const isKey = getStoreIsKey();
+	if(isKey == "1"){
+		dataForm.username = encryptAES(username);
+		dataForm.newPassword = encryptAES(newPassword);
+		dataForm.password = encryptAES(password);
+	}
+	
+	return request({
         url: '/initPassword',
         method: 'PUT',
 		header: {
 		  isToken: false,
 		  repeatSubmit: false
 		},
-        data: {
-			username: username,
-            newPassword: newPassword,
-            password: password
-        },
+        data: dataForm,
     })
 }
+
+export const getIsKey = ():Promise<any> =>{
+	return request({
+		url: '/crypto/isKey',
+		method: 'GET'
+	})
+}

+ 6 - 2
manifest.json

@@ -2,8 +2,8 @@
 	"name": "工效通APP",
 	"appid": "__UNI__1050C07",
 	"description": "工效通任务管理平台",
-	"versionName": "1.2.4",
-	"versionCode": "124",
+	"versionName": "1.2.7",
+	"versionCode": "127",
 	"uni-app-x": {},
 	"quickapp": {},
 	"mp-weixin": {
@@ -53,6 +53,10 @@
 		],
 		"networkSecurityConfig": "@xml/network_security_config",
 		"distribute": {
+			"untrustedCa": "allow",  // 允许不受信任的CA证书
+			"ssl": {
+			  "verify": false  // 可选:不验证SSL证书
+			},
 			"modules": {
 				"uni-map": {},
 				"uni-location": {},

+ 10 - 13
pages/login/index.uvue

@@ -80,17 +80,18 @@
 
 <script setup lang="uts">
     import { ref, computed, onMounted } from 'vue'
-    import { loginByAccount, getUserInfo, resetPassword } from '../../api/auth/login'
+    import { loginByAccount, getUserInfo, resetPassword , getIsKey} from '../../api/auth/login'
 	import checkUpdate from '@/uni_modules/uni-upgrade-center-app/utils/check-update'
     import {
         saveAccessToken,
         saveUserInfo,
         getRememberedAccount,
         saveRememberedAccount,
-        clearRememberedAccount
+        clearRememberedAccount,
+		saveStoreIsKey,
+		getStoreIsKey
     } from '../../utils/storage'
     import { validatePassword } from '../../utils/validate'
-    import { encryptAES } from '../../utils/crypto'
     // @ts-ignore
     import manifest from '@/manifest.json'
 
@@ -182,18 +183,14 @@
             return
         }
 
-        // // 验证密码强度
-        // if (!validatePassword(password.value)) {
-        //     uni.showToast({
-        //         title: '密码强度不足:需包含数字、大小写字母、特殊字符,至少6位',
-        //         icon: 'none',
-        //         duration: 3000
-        //     })
-        //     return
-        // }
-
         try {
             loading.value = true
+
+			const resultKey = await getIsKey();
+			const resultKeyObj = resultKey as UTSJSONObject
+			const isKey = resultKeyObj["data"] as string |'0'
+			saveStoreIsKey(isKey);
+
             const result = await loginByAccount(username.value, password.value)
             // 提取 data 部分
             const resultObj = result as UTSJSONObject

+ 20 - 8
pages/profile/index.uvue

@@ -51,9 +51,12 @@
 
 <script setup lang="uts">
     import { ref, onMounted } from 'vue'
-    import { getUserInfo } from '../../utils/storage'
+    import { getUserInfo, getStoreIsKey } from '../../utils/storage'
     import { logout as logoutApi } from '../../api/auth/logout'
     import { useAuth } from '../../composables/useAuth'
+	import { encryptAES, decryptAES } from '../../utils/crypto'
+	import { getIsKey } from '../../api/auth/login'
+	
     // @ts-ignore
     import manifest from '@/manifest.json'
 
@@ -172,14 +175,23 @@
     onMounted(() => {
         const userInfo = getUserInfo()
         if (userInfo != null) {
+			
             const nickName = userInfo['nickName'] as string | null
-            userName.value = nickName ?? ''
-
-            const phone = userInfo['phone'] as string | null
-            if (phone != null && phone.length > 0) {
-                userPhone.value = phone
-            }
-
+			const phone = userInfo['phone'] as string | null
+			
+			const isKey = getStoreIsKey();
+			if(isKey == "1"){
+				userName.value = decryptAES(nickName ?? '')
+				if (phone != null && phone.length > 0) {
+					userPhone.value = decryptAES(phone ?? '')
+				}
+			}else{
+				userName.value = nickName ?? ''
+				if (phone != null && phone.length > 0) {
+					userPhone.value = phone
+				}
+			}
+            
             const deptName = userInfo['deptName'] as string | null
             if (deptName != null && deptName.length > 0) {
                 userDept.value = deptName

+ 58 - 0
uni_modules/tq-encrypt/changelog.md

@@ -0,0 +1,58 @@
+## 1.2.9(2025-06-18)
+iOS删除CFBundleSupportedPlatforms
+## 1.2.8(2025-03-23)
+### iOS新增RSA加解密
+## 1.2.7(2025-03-20)
+iOS GMObjC版本更新到3.3.8
+## 1.2.6(2024-07-15)
+### 新增Android平台RSA自定义密钥转换函数generateKeyPair
+## 1.2.5(2024-06-14)
+### 兼容旧版本的Android AES加密
+## 1.2.4(2024-06-12)
+### 更新使用说明
+## 1.2.3(2024-06-11)
+### Android更新hmacSHA1方法
+## 1.2.2(2024-06-11)
+### WEB端新增AES加密、解密功能
+## 1.2.1(2024-06-11)
+### 更新Android原AES加密方式为ECB模式
+## 1.2.0(2024-06-11)
+### iOS平台aes加密添加cbc模式
+## 1.1.9(2024-06-11)
+### android平台aes加密添加cbc模式
+## 1.1.8(2024-05-28)
+### 更新使用说明
+## 1.1.7(2024-05-28)
+### web端引入三方加密库解决bug
+## 1.1.6(2024-05-27)
+### iOS支持sm2加解密、新增hmacSHA1的iOS加密方式
+## 1.1.5(2024-05-25)
+### 更新iOS的SM3加密、SM4加解密方法
+## 1.1.4(2024-05-24)
+### 更新iOS的AES加密方法
+## 1.1.3(2024-05-13)
+### 更新说明文档
+## 1.1.2(2024-05-13)
+### 支持iOS的SHA1、SHA256加密
+## 1.1.1(2024-05-11)
+### 支持iOS的MD5加密
+## 1.1.0(2024-04-30)
+### 支持iOS的base64加密解密
+## 1.0.9(2024-04-03)
+### 更新sm2调用
+## 1.0.8(2024-03-28)
+### 更新支持web版本的md5、base64、sm4
+## 1.0.7(2024-03-26)
+### 更新后bug修改
+## 1.0.6(2024-02-03)
+说明更新
+## 1.0.5(2024-02-02)
+更新注意事项
+## 1.0.4(2024-02-02)
+说明更新
+## 1.0.3(2024-01-31)
+更新说明文档
+## 1.0.2(2024-01-19)
+### 更新使用说明
+## 1.0.1(2024-01-19)
+### 添加了RSA加密

+ 98 - 0
uni_modules/tq-encrypt/common/Base64Utils.uts

@@ -0,0 +1,98 @@
+export class Base64 {
+    private _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+    encode(input: string) : string {
+        let output = "";
+        let chr1 : number, chr2 : number, chr3 : number, enc1 : number, enc2 : number, enc3 : number, enc4 : number;
+        let i = 0;
+        input = this._utf8_encode(input);
+        while (i < input.length) {
+            chr1 = input.charCodeAt(i++);
+            chr2 = input.charCodeAt(i++);
+            chr3 = input.charCodeAt(i++);
+            enc1 = chr1 >> 2;
+            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
+            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
+            enc4 = chr3 & 63;
+            if (isNaN(chr2)) {
+                enc3 = enc4 = 64;
+            } else if (isNaN(chr3)) {
+                enc4 = 64;
+            }
+            output = output +
+                this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
+                this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
+        }
+        return output;
+    }
+ 
+    decode(input: string) : string {
+        let output = "";
+        let chr1 : number, chr2 : number, chr3 : number;
+        let enc1 : number, enc2 : number, enc3 : number, enc4 : number;
+        let i = 0;
+        input = input.replace(/[^A-Za-z0-9]/g, "");
+        while (i < input.length) {
+            enc1 = this._keyStr.indexOf(input.charAt(i++));
+            enc2 = this._keyStr.indexOf(input.charAt(i++));
+            enc3 = this._keyStr.indexOf(input.charAt(i++));
+            enc4 = this._keyStr.indexOf(input.charAt(i++));
+            chr1 = (enc1 << 2) | (enc2 >> 4);
+            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
+            chr3 = ((enc3 & 3) << 6) | enc4;
+            output = output + String.fromCharCode(chr1);
+            if (enc3 != 64) {
+                output = output + String.fromCharCode(chr2);
+            }
+            if (enc4 != 64) {
+                output = output + String.fromCharCode(chr3);
+            }
+        }
+        output = this._utf8_decode(output);
+        return output;
+    }
+ 
+    _utf8_encode(string: string) : string {
+        string = string.replace(/\r\n/g, "\n");
+        let utftext = "";
+        for (let n = 0; n < string.length; n++) {
+            const c = string.charCodeAt(n);
+            if (c < 128) {
+                utftext += String.fromCharCode(c);
+            } else if ((c > 127) && (c < 2048)) {
+                utftext += String.fromCharCode((c >> 6) | 192);
+                utftext += String.fromCharCode((c & 63) | 128);
+            } else {
+                utftext += String.fromCharCode((c >> 12) | 224);
+                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
+                utftext += String.fromCharCode((c & 63) | 128);
+            }
+        }
+        return utftext;
+    }
+ 
+    // private method for UTF-8 decoding
+    _utf8_decode(utftext: string) : string {
+        let string = "";
+        let i = 0;
+        let c = 0;
+        let c1 = 0;
+        let c2 = 0;
+        while (i < utftext.length) {
+            c = utftext.charCodeAt(i);
+            if (c < 128) {
+                string += String.fromCharCode(c);
+                i++;
+            } else if ((c > 191) && (c < 224)) {
+                c1 = utftext.charCodeAt(i + 1);
+                string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
+                i += 2;
+            } else {
+                c1 = utftext.charCodeAt(i + 1);
+                c2 = utftext.charCodeAt(i + 2);
+                string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
+                i += 3;
+            }
+        }
+        return string;
+    }
+}

+ 227 - 0
uni_modules/tq-encrypt/common/MD5Utils.uts

@@ -0,0 +1,227 @@
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
+var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance   */
+var chrsz = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+export function hex_md5(s:string): string { return binl2hex(core_md5(str2binl(s), s.length * chrsz)); }
+function b64_md5(s: string): string { return binl2b64(core_md5(str2binl(s), s.length * chrsz)); }
+function str_md5(s: string): string { return binl2str(core_md5(str2binl(s), s.length * chrsz)); }
+function hex_hmac_md5(key: string, data: string): string { return binl2hex(core_hmac_md5(key, data)); }
+function b64_hmac_md5(key: string, data: string): string { return binl2b64(core_hmac_md5(key, data)); }
+function str_hmac_md5(key: string, data: string): string { return binl2str(core_hmac_md5(key, data)); }
+
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function md5_vm_test(): boolean {
+  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
+}
+
+/*
+ * Calculate the MD5 of an array of little-endian words, and a bit length
+ */
+function core_md5(x : number[], len: number): number[] {
+  /* append padding */
+  x[len >> 5] |= 0x80 << ((len) % 32);
+  x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+  var a = 1732584193;
+  var b = -271733879;
+  var c = -1732584194;
+  var d = 271733878;
+
+  for (var i = 0; i < x.length; i += 16) {
+    var olda = a;
+    var oldb = b;
+    var oldc = c;
+    var oldd = d;
+
+    a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
+    d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
+    c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
+    b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
+    a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
+    d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
+    c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
+    b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
+    a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
+    d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
+    c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
+    b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
+    a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
+    d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
+    c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
+    b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
+
+    a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
+    d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
+    c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
+    b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
+    a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
+    d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
+    c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
+    b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
+    a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
+    d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
+    c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
+    b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
+    a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
+    d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
+    c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
+    b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
+
+    a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
+    d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
+    c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
+    b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
+    a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
+    d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
+    c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
+    b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
+    a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
+    d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
+    c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
+    b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
+    a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
+    d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
+    c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
+    b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
+
+    a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
+    d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
+    c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
+    b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
+    a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
+    d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
+    c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
+    b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
+    a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
+    d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
+    c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
+    b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
+    a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
+    d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
+    c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
+    b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
+
+    a = safe_add(a, olda);
+    b = safe_add(b, oldb);
+    c = safe_add(c, oldc);
+    d = safe_add(d, oldd);
+  }
+  return Array(a, b, c, d);
+}
+
+/*
+ * These functions implement the four basic operations the algorithm uses.
+ */
+function md5_cmn(q: number, a: number, b: number, x: number, s: number, t: number): number {
+  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
+}
+function md5_ff(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {
+  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
+}
+function md5_gg(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {
+  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
+}
+function md5_hh(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {
+  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
+}
+function md5_ii(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {
+  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
+}
+
+/*
+ * Calculate the HMAC-MD5, of a key and some data
+ */
+function core_hmac_md5(key: string, data: string): number[] {
+  var bkey = str2binl(key);
+  if (bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
+
+  var ipad = Array(16), opad = Array(16);
+  for (var i = 0; i < 16; i++) {
+    ipad[i] = bkey[i] ^ 0x36363636;
+    opad[i] = bkey[i] ^ 0x5C5C5C5C;
+  }
+
+  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
+  return core_md5(opad.concat(hash), 512 + 128);
+}
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x: number, y: number): number {
+  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+  return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function bit_rol(num: number, cnt: number): number {
+  return (num << cnt) | (num >>> (32 - cnt));
+}
+
+/*
+ * Convert a string to an array of little-endian words
+ * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
+ */
+function str2binl(str:string): number[] {
+  var bin = Array();
+  var mask = (1 << chrsz) - 1;
+  for (var i = 0; i < str.length * chrsz; i += chrsz)
+    bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32);
+  return bin;
+}
+
+/*
+ * Convert an array of little-endian words to a string
+ */
+function binl2str(bin : number[]): string {
+  var str = "";
+  var mask = (1 << chrsz) - 1;
+  for (var i = 0; i < bin.length * 32; i += chrsz)
+    str += String.fromCharCode((bin[i >> 5] >>> (i % 32)) & mask);
+  return str;
+}
+
+/*
+ * Convert an array of little-endian words to a hex string.
+ */
+function binl2hex(binarray: number[]): string {
+  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+  var str = "";
+  for (var i = 0; i < binarray.length * 4; i++) {
+    str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) +
+      hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF);
+  }
+  return str;
+}
+
+/*
+ * Convert an array of little-endian words to a base-64 string
+ */
+function binl2b64(binarray: number[]): string {
+  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  var str = "";
+  for (var i = 0; i < binarray.length * 4; i += 3) {
+    var triplet = (((binarray[i >> 2] >> 8 * (i % 4)) & 0xFF) << 16)
+      | (((binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4)) & 0xFF) << 8)
+      | ((binarray[i + 2 >> 2] >> 8 * ((i + 2) % 4)) & 0xFF);
+    for (var j = 0; j < 4; j++) {
+      if (i * 8 + j * 6 > binarray.length * 32) str += b64pad;
+      else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
+    }
+  }
+  return str;
+}

+ 598 - 0
uni_modules/tq-encrypt/common/SM4Utils.uts

@@ -0,0 +1,598 @@
+let lookup: Array<any> = [];
+let revLookup: Array<any> = [];
+let Arr = typeof Uint8Array !== "undefined" ? Uint8Array : Array;
+
+let code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+for (let i = 0, len = code.length; i < len; ++i) {
+    lookup[i] = code[i];
+    revLookup[code.charCodeAt(i)] = i;
+}
+
+// Support decoding URL-safe base64 strings, as Node.js does.
+// See: https://en.wikipedia.org/wiki/Base64#URL_applications
+revLookup["-".charCodeAt(0)] = 62;
+revLookup["_".charCodeAt(0)] = 63;
+
+function getLens(b64: any) {
+    let len = b64.length;
+
+    if (len % 4 > 0) {
+        throw new Error("Invalid string. Length must be a multiple of 4");
+    }
+
+    // Trim off extra bytes after placeholder bytes are found
+    // See: https://github.com/beatgammit/base64-js/issues/42
+    let validLen = b64.indexOf("=");
+    if (validLen === -1) validLen = len;
+
+    let placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4);
+
+    return [validLen, placeHoldersLen];
+}
+
+// base64 is 4/3 + up to two characters of the original data
+function byteLength(b64: any) {
+    let lens = getLens(b64);
+    let validLen = lens[0];
+    let placeHoldersLen = lens[1];
+    return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen;
+}
+
+function _byteLength(b64: any, validLen: any, placeHoldersLen: any) {
+    return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen;
+}
+
+function toByteArray(b64: any) {
+    let tmp : number;
+    let lens = getLens(b64);
+    let validLen = lens[0];
+    let placeHoldersLen = lens[1];
+
+    let arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));
+
+    let curByte = 0;
+
+    // if there are placeholders, only get up to the last complete 4 chars
+    let len = placeHoldersLen > 0 ? validLen - 4 : validLen;
+
+    let i: number;
+    for (i = 0; i < len; i += 4) {
+        tmp =
+            (revLookup[b64.charCodeAt(i)] << 18) |
+            (revLookup[b64.charCodeAt(i + 1)] << 12) |
+            (revLookup[b64.charCodeAt(i + 2)] << 6) |
+            revLookup[b64.charCodeAt(i + 3)];
+        arr[curByte++] = (tmp >> 16) & 0xff;
+        arr[curByte++] = (tmp >> 8) & 0xff;
+        arr[curByte++] = tmp & 0xff;
+    }
+
+    if (placeHoldersLen === 2) {
+        tmp =
+            (revLookup[b64.charCodeAt(i)] << 2) |
+            (revLookup[b64.charCodeAt(i + 1)] >> 4);
+        arr[curByte++] = tmp & 0xff;
+    }
+
+    if (placeHoldersLen === 1) {
+        tmp =
+            (revLookup[b64.charCodeAt(i)] << 10) |
+            (revLookup[b64.charCodeAt(i + 1)] << 4) |
+            (revLookup[b64.charCodeAt(i + 2)] >> 2);
+        arr[curByte++] = (tmp >> 8) & 0xff;
+        arr[curByte++] = tmp & 0xff;
+    }
+
+    return arr;
+}
+
+function tripletToBase64(num: any) {
+    return (
+        lookup[(num >> 18) & 0x3f] +
+        lookup[(num >> 12) & 0x3f] +
+        lookup[(num >> 6) & 0x3f] +
+        lookup[num & 0x3f]
+    );
+}
+
+function encodeChunk(uint8: any, start: any, end: any) {
+    let tmp: number;
+    let output: Array<any> = [];
+    for (let i = start; i < end; i += 3) {
+        tmp =
+            ((uint8[i] << 16) & 0xff0000) +
+            ((uint8[i + 1] << 8) & 0xff00) +
+            (uint8[i + 2] & 0xff);
+        output.push(tripletToBase64(tmp));
+    }
+    return output.join("");
+}
+
+function fromByteArray(uint8: any) {
+    let tmp : number;
+    let len = uint8.length;
+    let extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes
+    let parts: Array<string> = [];
+    let maxChunkLength = 16383; // must be multiple of 3
+
+    // go through the array every three bytes, we'll deal with trailing stuff later
+    for (let i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
+        parts.push(
+            encodeChunk(
+                uint8,
+                i,
+                i + maxChunkLength > len2 ? len2 : i + maxChunkLength
+            )
+        );
+    }
+
+    // pad the end with zeros, but make sure to not forget the extra bytes
+    if (extraBytes === 1) {
+        tmp = uint8[len - 1];
+        parts.push(lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f] + "==");
+    } else if (extraBytes === 2) {
+        tmp = (uint8[len - 2] << 8) + uint8[len - 1];
+        parts.push(
+            lookup[tmp >> 10] +
+                lookup[(tmp >> 4) & 0x3f] +
+                lookup[(tmp << 2) & 0x3f] +
+                "="
+        );
+    }
+
+    return parts.join("");
+}
+
+/**
+ * 国密SM4加密算法
+ * @author c.z.s
+ * @email 1048829253@qq.com
+ * @company GDT-ZWZX-DEV-PT
+ * @date 2018-07
+ */
+class SM4_Context {
+    mode: number = 1;
+    isPadding: boolean = true;
+    sk: Array<any> = new Array(32);
+}
+
+class SM4 {
+    SM4_ENCRYPT: number = 1;
+    SM4_DECRYPT: number = 0;
+
+    SboxTable: Array<any> = [
+        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,
+    ];
+
+    FK = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc];
+
+    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,
+    ];
+
+    GET_ULONG_BE(b: any, i: any) {
+        return (
+            ((b[i] & 0xff) << 24) |
+            ((b[i + 1] & 0xff) << 16) |
+            ((b[i + 2] & 0xff) << 8) |
+            (b[i + 3] & 0xff & 0xffffffff)
+        );
+    }
+
+    PUT_ULONG_BE(n: any, b: any, i: any) {
+        let t1 = 0xff & (n >> 24);
+        let t2 = 0xff & (n >> 16);
+        let t3 = 0xff & (n >> 8);
+        let t4 = 0xff & n;
+        b[i] = t1 > 128 ? t1 - 256 : t1;
+        b[i + 1] = t2 > 128 ? t2 - 256 : t2;
+        b[i + 2] = t3 > 128 ? t3 - 256 : t3;
+        b[i + 3] = t4 > 128 ? t4 - 256 : t4;
+    }
+
+    SHL(x: any, n: any) {
+        return (x & 0xffffffff) << n;
+    }
+
+    ROTL(x: any, n: any) {
+        let s = this.SHL(x, n);
+        let ss = x >> (32 - n);
+        return this.SHL(x, n) | (x >> (32 - n));
+    }
+
+    sm4Lt(ka: any) {
+        let bb = 0;
+        let c = 0;
+        let a = new Array(4);
+        let b = new Array(4);
+        this.PUT_ULONG_BE(ka, a, 0);
+        b[0] = this.sm4Sbox(a[0]);
+        b[1] = this.sm4Sbox(a[1]);
+        b[2] = this.sm4Sbox(a[2]);
+        b[3] = this.sm4Sbox(a[3]);
+        bb = this.GET_ULONG_BE(b, 0);
+        c =
+            bb ^
+            this.ROTL(bb, 2) ^
+            this.ROTL(bb, 10) ^
+            this.ROTL(bb, 18) ^
+            this.ROTL(bb, 24);
+        return c;
+    }
+
+    sm4F(x0: any, x1: any, x2: any, x3: any, rk: any) {
+        return x0 ^ this.sm4Lt(x1 ^ x2 ^ x3 ^ rk);
+    }
+
+    sm4CalciRK(ka: any) {
+        let bb = 0;
+        let rk = 0;
+        let a = new Array(4);
+        let b = new Array(4);
+        this.PUT_ULONG_BE(ka, a, 0);
+        b[0] = this.sm4Sbox(a[0]);
+        b[1] = this.sm4Sbox(a[1]);
+        b[2] = this.sm4Sbox(a[2]);
+        b[3] = this.sm4Sbox(a[3]);
+        bb = this.GET_ULONG_BE(b, 0);
+        rk = bb ^ this.ROTL(bb, 13) ^ this.ROTL(bb, 23);
+        return rk;
+    }
+
+    sm4Sbox(inch: any) {
+        let i = inch & 0xff;
+        let retVal = this.SboxTable[i];
+        return retVal > 128 ? retVal - 256 : retVal;
+    }
+
+    sm4_setkey_enc(ctx: any, key: any) {
+        if (ctx == null) {
+            alert("ctx is null!");
+            return false;
+        }
+        if (key == null || key.length < 16) {
+            alert("key error!");
+            return false;
+        }
+        ctx.mode = this.SM4_ENCRYPT;
+        this.tsm4_setkey(ctx.sk, key);
+    }
+    //生成解密密钥
+    sm4_setkey_dec(ctx: any, key: any) {
+        if (ctx == null) {
+            new Error("ctx is null!");
+        }
+
+        if (key == null || key.length !== 16) {
+            new Error("2key error!");
+        }
+
+        // let i = 0;
+        ctx.mode = 0;
+        this.tsm4_setkey(ctx.sk, key);
+        ctx.sk = ctx.sk.reverse();
+    }
+
+    tsm4_setkey(SK: Array<any>, key: any) {
+        let MK = new Array(4);
+        let k = new Array(36);
+        // let i = 0;
+        MK[0] = this.GET_ULONG_BE(key, 0);
+        MK[1] = this.GET_ULONG_BE(key, 4);
+        MK[2] = this.GET_ULONG_BE(key, 8);
+        MK[3] = this.GET_ULONG_BE(key, 12);
+        k[0] = MK[0] ^ this.FK[0];
+        k[1] = MK[1] ^ this.FK[1];
+        k[2] = MK[2] ^ this.FK[2];
+        k[3] = MK[3] ^ this.FK[3];
+        for (let i = 0; i < 32; i++) {
+            k[i + 4] =
+                k[i] ^
+                this.sm4CalciRK(k[i + 1] ^ k[i + 2] ^ k[i + 3] ^ this.CK[i]);
+            SK[i] = k[i + 4];
+        }
+    }
+    padding(input: any, mode: any) {
+        if (input == null) {
+            return null;
+        }
+        let ret: Array<number> = [];
+        if (mode == this.SM4_ENCRYPT) {
+            let p = parseInt((16 - (input.length % 16)).toString(), 10);
+			ret = input.slice(0);
+			for (let i = 0; i < p; i++) {
+			  ret[input.length + i] = p;
+			}
+        } else {
+            let p = input[input.length - 1];
+            ret = input.slice(0, input.length - p);
+        }
+        return ret;
+    }
+    sm4_one_round(sk: any, input: any, output: any) {
+        let i = 0;
+        let ulbuf = new Array(36);
+        ulbuf[0] = this.GET_ULONG_BE(input, 0);
+        ulbuf[1] = this.GET_ULONG_BE(input, 4);
+        ulbuf[2] = this.GET_ULONG_BE(input, 8);
+        ulbuf[3] = this.GET_ULONG_BE(input, 12);
+        while (i < 32) {
+            ulbuf[i + 4] = this.sm4F(
+                ulbuf[i],
+                ulbuf[i + 1],
+                ulbuf[i + 2],
+                ulbuf[i + 3],
+                sk[i]
+            );
+            i++;
+        }
+        this.PUT_ULONG_BE(ulbuf[35], output, 0);
+        this.PUT_ULONG_BE(ulbuf[34], output, 4);
+        this.PUT_ULONG_BE(ulbuf[33], output, 8);
+        this.PUT_ULONG_BE(ulbuf[32], output, 12);
+    }
+
+    sm4_crypt_ecb(ctx: any, input: any) {
+        if (input == null) {
+            alert("input is null!");
+        }
+        if (ctx.isPadding && ctx.mode == this.SM4_ENCRYPT) {
+            input = this.padding(input, this.SM4_ENCRYPT);
+        }
+
+        let i = 0;
+        let length = input.length;
+        let bous = new Array<any>();
+        for (; length > 0; length -= 16) {
+            let out = new Array(16);
+            let ins = input.slice(i * 16, 16 * (i + 1));
+            this.sm4_one_round(ctx.sk, ins, out);
+            bous = bous.concat(out);
+            i++;
+        }
+
+        let output = bous;
+        if (ctx.isPadding && ctx.mode == this.SM4_DECRYPT) {
+            output = this.padding(output, this.SM4_DECRYPT)!;
+        }
+        for (let ki = 0; ki < output.length; ki++) {
+			if (output[ki] < 0) {
+				output[ki] = output[ki] + 256;
+			}
+		}
+		return output;
+    }
+
+    sm4_crypt_cbc(ctx: any, iv: any, input: any) {
+        if (iv == null || iv.length != 16) {
+            alert("iv error!");
+        }
+
+        if (input == null) {
+            alert("input is null!");
+        }
+
+        if (ctx.isPadding && ctx.mode == this.SM4_ENCRYPT) {
+            input = this.padding(input, this.SM4_ENCRYPT);
+        }
+
+        let i = 0;
+        let length = input.length;
+        let bous = new Array<number>();
+        if (ctx.mode == this.SM4_ENCRYPT) {
+            let k = 0;
+            for (; length > 0; length -= 16) {
+                let out = new Array(16);
+                let out1 = new Array(16);
+                let ins = input.slice(k * 16, 16 * (k + 1));
+
+                for (i = 0; i < 16; i++) {
+                    out[i] = ins[i] ^ iv[i];
+                }
+                this.sm4_one_round(ctx.sk, out, out1);
+                iv = out1.slice(0, 16);
+                bous = bous.concat(out1);
+                k++;
+            }
+        } else {
+            let temp = [];
+            let k = 0;
+            for (; length > 0; length -= 16) {
+                let out = new Array(16);
+                let out1 = new Array(16);
+                let ins = input.slice(k * 16, 16 * (k + 1));
+                temp = ins.slice(0, 16);
+                this.sm4_one_round(ctx.sk, ins, out);
+                for (i = 0; i < 16; i++) {
+                    out1[i] = out[i] ^ iv[i];
+                }
+                iv = temp.slice(0, 16);
+                bous = bous.concat(out1);
+                k++;
+            }
+        }
+
+        let output = bous;
+        if (ctx.isPadding && ctx.mode == this.SM4_DECRYPT) {
+            output = this.padding(output, this.SM4_DECRYPT)!;
+        }
+
+        for (let i = 0; i < output.length; i++) {
+            if (output[i] < 0) {
+                output[i] = output[i] + 256;
+            }
+        }
+        return output;
+    }
+}
+
+const stringToByte = function (str: any) {
+    let bytes = new Array<number>();
+    let len: number, c : number;
+    len = str.length;
+    for (let i = 0; i < len; i++) {
+        c = str.charCodeAt(i);
+        if (c >= 0x010000 && c <= 0x10ffff) {
+            bytes.push(((c >> 18) & 0x07) | 0xf0);
+            bytes.push(((c >> 12) & 0x3f) | 0x80);
+            bytes.push(((c >> 6) & 0x3f) | 0x80);
+            bytes.push((c & 0x3f) | 0x80);
+        } else if (c >= 0x000800 && c <= 0x00ffff) {
+            bytes.push(((c >> 12) & 0x0f) | 0xe0);
+            bytes.push(((c >> 6) & 0x3f) | 0x80);
+            bytes.push((c & 0x3f) | 0x80);
+        } else if (c >= 0x000080 && c <= 0x0007ff) {
+            bytes.push(((c >> 6) & 0x1f) | 0xc0);
+            bytes.push((c & 0x3f) | 0x80);
+        } else {
+            bytes.push(c & 0xff);
+        }
+    }
+    return bytes;
+};
+
+const byteToString = function (arr: any) {
+    if (typeof arr === "string") {
+        return arr;
+    }
+    let str = "",
+        _arr = arr;
+    for (let i = 0; i < _arr.length; i++) {
+        let one = _arr[i].toString(2),
+            v = one.match(/^1+?(?=0)/);
+        if (v && one.length == 8) {
+            let bytesLength = v[0].length;
+            let store = _arr[i].toString(2).slice(7 - bytesLength);
+            for (let st = 1; st < bytesLength; st++) {
+                store += _arr[st + i].toString(2).slice(2);
+            }
+            str += String.fromCharCode(parseInt(store, 2));
+            i += bytesLength - 1;
+        } else {
+            str += String.fromCharCode(_arr[i]);
+        }
+    }
+    return str;
+};
+
+export class SM4Util {
+    // 加密
+    encryptData_CBC(plainText: any, pubKey: any, iv: any) {
+        try {
+            let sm4 = new SM4();
+            let ctx = new SM4_Context();
+            ctx.isPadding = true;
+            ctx.mode = sm4.SM4_ENCRYPT;
+
+            let keyBytes = toByteArray(pubKey);
+
+            sm4.sm4_setkey_enc(ctx, keyBytes);
+            let encrypted = sm4.sm4_crypt_cbc(
+                ctx,
+                iv,
+                stringToByte(plainText)
+            );
+            let cipherText = fromByteArray(encrypted);
+            if (cipherText != null && cipherText.trim().length > 0) {
+                cipherText.replace(/(\s*|\t|\r|\n)/g, "");
+            }
+            return cipherText;
+        } catch (e) {
+            console.error(e);
+            return null;
+        }
+    }
+    decryptData_CBC(cipherText: any, pubKey: any, iv: any) {
+        try {
+            let sm4 = new SM4();
+            let ctx = new SM4_Context();
+            ctx.isPadding = true;
+            ctx.mode = sm4.SM4_ENCRYPT;
+            let keyBytes = toByteArray(pubKey);
+            sm4.sm4_setkey_dec(ctx, keyBytes);
+            let decrypted = sm4.sm4_crypt_cbc(
+                ctx,
+                iv,
+                toByteArray(cipherText)
+            );
+
+            return byteToString(decrypted).replace(/(\x10|\x04|\x05)/g, "").replaceAll("\b","");
+        } catch (e) {
+            console.error(e);
+            return null;
+        }
+    }
+	
+	// 加密_ECB
+	encryptData_ECB(plainText: any, secretKey: string) {
+	    try {
+	        let sm4 = new SM4();
+	        let ctx = new SM4_Context();
+	        ctx.isPadding = true;
+	        ctx.mode = sm4.SM4_ENCRYPT;
+	
+	        let keyBytes = stringToByte(secretKey);
+	
+	        sm4.sm4_setkey_enc(ctx, keyBytes);
+	        let encrypted = sm4.sm4_crypt_ecb(
+	            ctx,
+	            stringToByte(plainText)
+	        );
+	        let cipherText = fromByteArray(encrypted);
+	        if (cipherText != null && cipherText.trim().length > 0) {
+	            cipherText.replace(/(\s*|\t|\r|\n)/g, "");
+	        }
+	        return cipherText;
+	    } catch (e) {
+	        console.error(e);
+	        return null;
+	    }
+	}
+	// 解密_ECB
+	decryptData_ECB(plainText: any, secretKey: string) {
+	    try {
+	        let sm4 = new SM4();
+	        let ctx = new SM4_Context();
+	        ctx.isPadding = true;
+	        ctx.mode = sm4.SM4_DECRYPT;
+	
+	        let keyBytes = stringToByte(secretKey);
+	
+	        sm4.sm4_setkey_dec(ctx, keyBytes);
+	        let decrypted = sm4.sm4_crypt_ecb(
+	            ctx,
+	            toByteArray(plainText)
+	        );
+	        return byteToString(decrypted);
+	    } catch (e) {
+	        console.error(e);
+	        return null;
+	    }
+	}
+}

+ 151 - 0
uni_modules/tq-encrypt/common/index.uts

@@ -0,0 +1,151 @@
+import { hex_md5 } from "./MD5Utils.uts";
+
+import { CommonSync,sm4Sync,ivSync,sm2Validate } from "../utssdk/interface.uts";
+
+import { Base64 } from "./Base64Utils.uts";
+import sm from 'miniprogram-sm-crypto';
+import CryptoJS from "crypto-js";
+
+// md5加密
+export const md5Sync : CommonSync = function (md5Str : string) : string {
+	const res : string = hex_md5(md5Str);
+	return res;
+}
+
+// base64加密
+export const base64EncodeSync : CommonSync = function (str : string) : string {
+	const base64 = new Base64()
+	console.log(str);
+	const res = base64.encode(str)
+	return res;
+}
+
+// base64解密
+export const base64DecodeSync : CommonSync = function (str : string) : string {
+	const base64 = new Base64()
+	const res = base64.decode(str)
+	return res;
+}
+
+// 国产SM4ECB加密
+export const sm4ECBEncryptSync : sm4Sync = function (dataString : string, keySM4 : string) : string {
+	const res : string = sm.sm4.encrypt(dataString,keySM4)
+	return res;
+}
+
+// 国产SM4ECB解密
+export const sm4ECBDecryptSync : sm4Sync = function (dataString : string, keySM4 : string) : string {
+	const res : string = sm.sm4.decrypt(dataString,keySM4)
+	return res;
+}
+
+// 国产SM4CBC加密
+export const sm4CBCEncryptSync : ivSync = function (dataString : string, keySM4 : string, iv: string) : string {
+	const res : string = sm.sm4.encrypt(dataString, keySM4, {mode: 'cbc', iv: iv})
+	return res;
+}
+
+// 国产SM4CBC解密
+export const sm4CBCDecryptSync : ivSync = function (dataString : string, keySM4 : string, iv: string) : string {
+	const res : string = sm.sm4.decrypt(dataString, keySM4, {mode: 'cbc', iv: iv})
+	return res;
+}
+
+// 国产SM3加密
+export const sm3EncryptSync : CommonSync = function (dataString : string) : string {
+	let res = sm.sm3(dataString)
+	return res;
+}
+
+// 国产SM2非对称公钥加密
+export const sm2EncryptSync : sm4Sync = function (dataString : string, publicKey : string) : string {
+	let res = sm.sm2.doEncrypt(dataString, publicKey, 1);
+	return res;
+}
+
+// 国产SM2非对称私钥解密
+export const sm2DecryptSync : sm4Sync = function (dataString : string, privateKey : string) : string {
+	let res = sm.sm2.doDecrypt(dataString, privateKey, 1);
+	return res;
+}
+
+// sm2签名
+export const sm2PubSignSync : sm4Sync = function (dataString : string, privateKey : string) : string {
+	const sign = sm.sm2.doSignature(dataString, privateKey);
+	return sign;
+}
+// sm2验签
+export const sm2PubSignValSync : sm2Validate = function (dataString : string, publicKey : string, sign : string) : boolean {
+	const verifySign = sm.sm2.doVerifySignature(dataString, sign, publicKey);
+	return verifySign;
+}
+
+// AES对称加密
+export const aesEncryptSync : sm4Sync = function (plainText : string, keyAES : string) : string {
+	let key = CryptoJS.enc.Utf8.parse(keyAES);
+	let srcs = CryptoJS.enc.Utf8.parse(plainText);
+	
+	let encrypted = CryptoJS.AES.encrypt(srcs, key, {
+	  mode: CryptoJS.mode.ECB,
+	  padding: CryptoJS.pad.Pkcs7
+	});
+	return encrypted.toString();
+}
+
+// AES对称解密
+export const aesDecryptSync : sm4Sync = function (encryptedBase64 : string, keyAES : string) : string {
+	let key = CryptoJS.enc.Utf8.parse(keyAES);
+	
+	let decrypt = CryptoJS.AES.decrypt(encryptedBase64, key, {
+	  mode: CryptoJS.mode.ECB,
+	  padding: CryptoJS.pad.Pkcs7
+	});
+	let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
+	return decryptedStr.toString();
+}
+
+// AES CBC对称加密
+export const aesCBCEncryptSync : ivSync = function (plainText : string, keyAES : string, ivStr: string) : string {
+	let key = CryptoJS.enc.Utf8.parse(keyAES);
+	let iv = CryptoJS.enc.Utf8.parse(ivStr);
+	let srcs = CryptoJS.enc.Utf8.parse(plainText);
+	
+	let encrypted = CryptoJS.AES.encrypt(srcs, key, {
+	  iv,
+	  mode: CryptoJS.mode.CBC,
+	  padding: CryptoJS.pad.Pkcs7
+	});
+	return encrypted.toString();
+}
+
+// AES CBC对称解密
+export const aesCBCDecryptSync : ivSync = function (encryptedBase64 : string, keyAES : string, ivStr: string) : string {
+	let key = CryptoJS.enc.Utf8.parse(keyAES);
+	let iv = CryptoJS.enc.Utf8.parse(ivStr);
+	
+	let decrypt = CryptoJS.AES.decrypt(encryptedBase64, key, {
+	  iv,
+	  mode: CryptoJS.mode.CBC,
+	  padding: CryptoJS.pad.Pkcs7
+	});
+	let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
+	return decryptedStr.toString();
+}
+
+// SHA1加密
+export const sha1Sync : CommonSync = function (str : string) : string {
+	let sha1 = CryptoJS.SHA1(str);
+	return sha1.toString();
+}
+
+// SHA256加密
+export const sha256Sync : CommonSync = function (str : string) : string {
+	let sha256 = CryptoJS.SHA256(str);
+	return sha256.toString();
+}
+
+// hmacSHA1加密
+export const hmacSHA1Sync : sm4Sync = function (plaintext : string, key : string) : string {
+	let res = CryptoJS.HmacSHA1(plaintext, key)
+	return res.toString();
+}

+ 91 - 0
uni_modules/tq-encrypt/package.json

@@ -0,0 +1,91 @@
+{
+	"id": "tq-encrypt",
+	"displayName": "Android端的AES、MD5、RSA、SHA、SM2、SM3、SM4加密解密",
+	"version": "1.2.9",
+	"description": "Android端的AES、MD5、RSA、SHA、SM2、SM3、SM4加密解密的封装使用",
+	"keywords": [
+        "tq-encrypt"
+    ],
+	"repository": "",
+	"engines": {
+		"HBuilderX": "^3.6.8"
+	},
+	"dcloudext": {
+		"type": "uts",
+		"sale": {
+			"regular": {
+				"price": "0.00"
+			},
+			"sourcecode": {
+				"price": "0.00"
+			}
+		},
+		"contact": {
+			"qq": "1307905648"
+		},
+		"declaration": {
+			"ads": "无",
+			"data": "无",
+			"permissions": "无"
+		},
+		"npmurl": ""
+	},
+	"uni_modules": {
+		"dependencies": [],
+		"encrypt": [],
+		"platforms": {
+			"cloud": {
+				"tcb": "y",
+				"aliyun": "y",
+				"alipay": "y"
+			},
+			"client": {
+				"Vue": {
+					"vue2": "y",
+					"vue3": "y"
+				},
+				"App": {
+                    "app-android": {
+                        "minVersion": "21"
+                    },
+                    "app-ios": {
+                        "minVersion": "13"
+                    },
+                    "app-harmony": "u"
+                },
+				"H5-mobile": {
+					"Safari": "y",
+					"Android Browser": "y",
+					"微信浏览器(Android)": "y",
+					"QQ浏览器(Android)": "y"
+				},
+				"H5-pc": {
+					"Chrome": "n",
+					"IE": "n",
+					"Edge": "n",
+					"Firefox": "n",
+					"Safari": "n"
+				},
+				"小程序": {
+					"微信": "n",
+					"阿里": "n",
+					"百度": "n",
+					"字节跳动": "n",
+					"QQ": "n",
+					"钉钉": "n",
+					"快手": "n",
+					"飞书": "n",
+					"京东": "n"
+				},
+				"快应用": {
+					"华为": "n",
+					"联盟": "n"
+				}
+			}
+		}
+	},
+	"dependencies": {
+		"miniprogram-sm-crypto": "^0.3.6",
+		"crypto-js": "^4.2.0"
+	}
+}

+ 170 - 0
uni_modules/tq-encrypt/readme.md

@@ -0,0 +1,170 @@
+# tq-encrypt
+### 开发文档
+[UTS 语法](https://uniapp.dcloud.net.cn/tutorial/syntax-uts.html)
+[UTS API插件](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html)
+[UTS 组件插件](https://uniapp.dcloud.net.cn/plugin/uts-component.html)
+[Hello UTS](https://gitcode.net/dcloud/hello-uts)
+
+> **注意:**
+> 
+> 如果需要支持web,本插件依赖第三方插件miniprogram-sm-crypto和crypto-js,你需要安装它。可以到插件的目录下安装`npm install`,也可以全局目录下安装`npm install miniprogram-sm-crypto crypto-js --save`,只支持Android、iOS不需要安装
+
+### 使用说明
+
+|名称|描述|参数|说明|支持平台|
+|:--|:--|:--|:--|:--|
+|md5Sync|md5加密|str:string|返回值:string  加密出来的字母是大写|Android、Web、iOS|
+|base64EncodeSync|base64加密|str:string|返回值:string|Android、Web、iOS|
+|base64DecodeSync|base64解密|str:string|返回值:string|Android、Web、iOS|
+|sm4ECBEncryptSync|sm4 ECB加密|参数一:str:string 参数二:key:string|返回值:string js中sm4加密ECB一般为默认|Android、Web、iOS|
+|sm4ECBDecryptSync|sm4 ECB解密|参数一:str:string 参数二:key:string|返回值:string|Android、Web、iOS|
+|sm4CBCEncryptSync|sm4 CBC加密|参数一:str:string 参数二:key:string 参数三:iv:string|返回值:string|Android、Web、iOS|
+|sm4CBCDecryptSync|sm4 CBC解密|参数一:str:string 参数二:key:string 参数三:iv:string|返回值:string|Android、Web、iOS|
+|sm3EncryptSync|sm3加密|str:string|返回值:string|Android、Web、iOS|
+|sm2EncryptSync|国产SM2非对称公钥加密|参数一:dataString : string 参数二:publicKey : string|返回值:string|Android、Web、iOS|
+|sm2DecryptSync|国产SM2非对称私钥解密|参数一:dataString : string 参数二:privateKey : string|返回值:string|Android、Web、iOS|
+|sm2PubSignSync|sm2私钥签名|参数一:dataString : string 参数二:privateKey : string|返回值:string|Android、Web、iOS|
+|sm2PubSignValSync|sm2验签|参数一:dataString : string 参数二:publicKey : string 参数三:sign : string|返回值:boolean|Android、Web、iOS|
+|aesEncryptSync|AES ECB对称加密|参数一:str:string 参数二:key:string [参数三:isHex: boolean(默认值为false,值为true是旧版返回HEX值)目前只有Android支持]|返回值:string `AES加密方式为ECB模式,返回的是base64加密数据`|Android、iOS、Web|
+|aesDecryptSync|AES ECB对称解密|参数一:str:string 参数二:key:string [参数三:isHex: boolean(默认值为false,值为true是旧版返回HEX值)目前只有Android支持]|返回值:string `AES解密密方式为ECB模式`|Android、iOS、Web|
+|sha1Sync|SHA1加密|str:string|返回值:string|Android、iOS、Web|
+|sha256Sync|SHA256加密|str:string|返回值:string|Android、iOS、Web|
+|rsaEncryptSync|RSA非对称加密|参数一:dataString : string  参数二:keyPair : KeyPair  参数三:type : KeyType|返回值:string|Android|
+|rsaDecryptSync|RSA非对称解密|参数一:dataString : string  参数二:keyPair : KeyPair  参数三:type : KeyType|返回值:string|Android|
+|rsaEncryptSync|RSA非对称加密|参数一:dataString : string  参数二:key:string|返回值:string(base64字符串)|iOS|
+|rsaDecryptSync|RSA非对称解密|参数一:dataString : string  参数二:key:string|返回值:string|iOS|
+|rsaSHA256PrivateSync|RSA SHA256签名|参数一:dataString : string  参数二:keyPair : KeyPair|返回值:string|Android|
+|rsaMD5PrivateSync|RSA MD5签名|参数一:dataString : string  参数二:keyPair : KeyPair|返回值:string|Android|
+|rsaSHA256PubValSync|RSA SHA256签名验签|参数一:dataString : string  参数二:result: string  参数三:keyPair : KeyPair|返回值:boolean|Android|
+|rsaMD5PubValSync|RSA MD5签名验签|参数一:dataString : string  参数二:result: string  参数三:keyPair : KeyPair|返回值:boolean|Android|
+|hmacSHA1Sync|hmacSHA1加密|参数一:plaintext : string 参数二:key : string|返回值:string|Android、iOS、Web|
+|aesCBCEncryptSync|aes CBC加密|参数一:str:string 参数二:key:string 参数三:iv:string|返回值:string|Android、iOS、Web|
+|aesCBCDecryptSync|aes CBC解密|参数一:str:string 参数二:key:string 参数三:iv:string|返回值:string|Android、iOS、Web|
+|generateKeyPair|生成RSA KeyPair密钥|参数一:pubStr:string(只接受hex字符串) 参数二:privateStr:string(只接受hex字符串)|返回值:KeyPair|Android|
+
+### 使用示例
+
+``` html
+<template>
+	<view>
+		<button @tap="testMD5">测试md5</button>
+		<button @tap="testbase64encode">测试base64encode</button>
+		<button @tap="testSM4">测试国产SM加密</button>
+		<button @tap="testaes">测试aes</button>
+		<button @tap="testSHA">测试sha</button>
+		<button @tap="testRSA">测试RSA</button>
+	</view>
+</template>
+
+<script lang="uts">
+	import { md5Sync, base64EncodeSync, rsaEncryptSync, getKeyPair, KeyType, rsaDecryptSync, rsaSHA256PrivateSync, rsaMD5PrivateSync, rsaSHA256PubValSync, rsaMD5PubValSync, base64DecodeSync, sm4ECBEncryptSync, sm4ECBDecryptSync, sm4CBCEncryptSync, sm4CBCDecryptSync, aesEncryptSync, aesDecryptSync, sha1Sync, sha256Sync, sm3EncryptSync,sm2KeyPair,sm2EncryptSync,sm2DecryptSync,sm2PubSignSync,sm2PubSignValSync,aesCBCEncryptSync,aesCBCDecryptSync } from "@/uni_modules/tq-encrypt"
+	export default {
+		data() {
+			return {
+				str: "123456"
+			}
+		},
+		methods: {
+			testMD5() {
+				const md5 = md5Sync(this.str)
+				console.log(md5);
+			},
+			testbase64encode() {
+				const str = base64EncodeSync("212321")
+				console.log(str);
+
+				const rom = base64DecodeSync(str)
+				console.log(rom);
+			},
+			testSM4() {
+				const key = 'D607A82C09F938809778B25A2F98DFA1';
+				let data = {
+					"ac": md5Sync("123456").toLowerCase(),
+					"grant_type": "onlyPassword",
+					"name": "arguments"
+				}
+				console.log(JSON.stringify(data));
+				// js的sm4解密一般ECB为默认
+				const sm4 = sm4ECBEncryptSync(JSON.stringify(data), key)
+				console.log(sm4);
+				const sm3 = sm3EncryptSync(JSON.stringify(data))
+				console.log(sm3);
+				const origin = sm4ECBDecryptSync(sm4, key)
+				console.log(origin);
+				const iv = 'fedcba98765432100123456789abcdef';
+				const cbcsm4 = sm4CBCEncryptSync("123456",key,iv)
+				console.log(cbcsm4);
+				const origincbcsm4 = sm4CBCDecryptSync(cbcsm4,key,iv)
+				console.log(origincbcsm4);
+				
+				const arr = sm2KeyPair()// 返回密钥 0 公钥 1 私钥
+				console.log(arr);
+				const sm2 = sm2EncryptSync("123456",arr[0])// 公钥加密
+				console.log(sm2);
+				const sm2origin = sm2DecryptSync(sm2,arr[1])// 私钥解密
+				console.log(sm2origin);
+
+				const sign = sm2PubSignSync(sm2,arr[1])// 私钥签名
+				console.log(sign);
+				const bool = sm2PubSignValSync(sm2,arr[0],sign) // 公钥验签
+				console.log(bool);
+			},
+			testaes() {
+				const res = aesEncryptSync("123456", "94E114C6A898CD39B602C8269AD33780")
+				console.log(res);
+				const dom = aesDecryptSync("3AA827B7EB35B4F522360B486EDB918C", "94E114C6A898CD39B602C8269AD33780")
+				console.log(dom);
+				// #ifdef APP-ANDROID
+				const key = "457E900861A541B7BA69455073A3A56A"
+				const iv = "457E900861A541B7"
+				const aes = aesCBCEncryptSync("123456", key, iv)
+				console.log(aes);
+				const origin = aesCBCDecryptSync(aes,key,iv)
+				console.log(origin);
+				// #endif
+			},
+			testSHA() {
+				const res1 = sha1Sync("123456")
+				const res2 = sha256Sync("123456")
+				console.log(res1, res2);
+			},
+			testRSA() {
+				const key = getKeyPair()
+				const res = rsaEncryptSync("123456", key, KeyType.PUB)//公钥加密
+				console.log(res);
+				const origin = rsaDecryptSync(res, key, KeyType.PRI)//私钥解密
+				console.log(origin);
+
+				const res1 = rsaEncryptSync("123456", key, KeyType.PRI)//私钥加密
+				console.log(res1);
+				const origin1 = rsaDecryptSync(res1, key, KeyType.PUB)//公钥解密
+				console.log(origin1);
+
+				const res2 = rsaSHA256PrivateSync("123456", key)//私钥对明文数据SHA256签名
+				console.log(res2);
+				const res3 = rsaMD5PrivateSync("123456", key)//私钥对明文数据MD5签名
+				console.log(res3);
+				const res4 = rsaSHA256PubValSync("123456", res2, key) // 公钥对SHA256签名验签
+				console.log(res4);
+				const res5 = rsaMD5PubValSync("123456", res3, key) // 公钥对MD5签名验签
+				console.log(res5);
+			}
+		}
+	}
+</script>
+```
+
+
+### 注意
+
+1、本插件包含原生第三方库需要配置gradle库和sdk库
+
+[Android UTS扩展开发](https://uniapp.dcloud.net.cn/tutorial/run/uts-development-android.html)
+
+![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/%E9%85%8D%E7%BD%AE.png)
+
+![](https://cdn.jsdelivr.net/gh/qitiandear/qtpic/img/20240328113941.png)
+
+HBuilder X新版本更新后需要升级gradle库,本人使用的版本是gradle8.2.1配置jdk路径为jdk17,其他版本可使用官方推荐版本
+
+> ps: 如果有问题可以咨询作者,本人QQ:1307905648,也可以在评论区留言截图配置环境和错误信息

+ 6 - 0
uni_modules/tq-encrypt/utssdk/app-android/config.json

@@ -0,0 +1,6 @@
+{
+  "minSdkVersion": "21",
+  "dependencies": [
+	  "com.github.mtjsoft:lib_encryption:1.4.0"
+  ]
+}

+ 256 - 0
uni_modules/tq-encrypt/utssdk/app-android/index.uts

@@ -0,0 +1,256 @@
+/* 引入 interface.uts 文件中定义的变量 */
+import { CommonSync, sm4Sync, ivSync, rsaSync, KeyType, rsaCommonSync, rsaValidate, sm2Validate, hexSync } from '../interface.uts';
+export { KeyType }
+
+/**
+ * 引入三方库
+ */
+
+import MD5Util from 'cn.mtjsoft.lib_encryption.MD5.MD5Util';
+import Base64Util from 'cn.mtjsoft.lib_encryption.BASE64.Base64Util';
+import AESUtil from 'cn.mtjsoft.lib_encryption.AES.AESUtil';
+import Util from 'cn.mtjsoft.lib_encryption.utils.Util';
+import SHAUtil from 'cn.mtjsoft.lib_encryption.SHA.SHAUtil';
+import RSAUtil from 'cn.mtjsoft.lib_encryption.RSA.RSAUtil';
+import SM2Util from 'cn.mtjsoft.lib_encryption.SM2.SM2Util';
+import SM3Util from 'cn.mtjsoft.lib_encryption.SM3.SM3Util';
+import SM4Util from 'cn.mtjsoft.lib_encryption.SM4.SM4Util';
+import KeyPair from 'java.security.KeyPair';
+import Cipher from 'javax.crypto.Cipher';
+import IvParameterSpec from 'javax.crypto.spec.IvParameterSpec';
+import SecretKeySpec from 'javax.crypto.spec.SecretKeySpec';
+import Mac from 'javax.crypto.Mac';
+
+/**
+ * 同步方法
+ *
+ * uni-app项目中(vue/nvue)调用示例:
+ * 1、引入方法声明 import { md5Sync,base64EncodeSync,base64DecodeSync } from "@/uni_modules/tq-encrypt"
+ * 2、方法调用 md5Sync('123456')  base64EncodeSync("212321")
+ *
+ * uni-app x项目(uvue)中调用示例:
+ * 1、引入方法及参数声明 import { md5Sync,base64EncodeSync,base64DecodeSync } from "@/uni_modules/tq-encrypt";
+ * 2、方法调用 md5Sync('123456')  base64DecodeSync("MjEyMzIx")
+ */
+
+// md5加密
+export const md5Sync : CommonSync = function (md5Str : string) : string {
+	const res : string = MD5Util.stringMD5(md5Str);
+	return res;
+}
+// base64加密
+export const base64EncodeSync : CommonSync = function (str : string) : string {
+	const res : string = Base64Util.encode(str.toByteArray());
+	return res;
+}
+
+// base64解密
+export const base64DecodeSync : CommonSync = function (str : string) : string {
+	const res : string = String(Base64Util.decode(str));
+	return res;
+}
+
+// AES对称加密
+export function aesEncryptSync(dataString : string, keyAES : string, isHex: boolean = false) : string {
+	if (isHex) {
+		const encrypt = AESUtil.encrypt(dataString.toByteArray(), Util.hexStr2Bytes(keyAES));
+		const res : string = Util.byte2HexStr(encrypt);
+		return res;
+	} else{
+		const byteContent = dataString.toByteArray();
+		const enCodeFormat = keyAES.toByteArray();
+		const secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
+		const cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+		cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
+		
+		const encryptedBytes = cipher.doFinal(byteContent);
+		
+		// 同样对加密后数据进行 base64 编码
+		return Base64Util.encode(encryptedBytes);
+	}
+}
+
+// AES对称解密
+export function aesDecryptSync(dataString : string, keyAES : string, isHex: boolean = false) : string {
+	if (isHex) {
+		const res : string = String(AESUtil.decrypt(Util.hexStr2Bytes(dataString), Util.hexStr2Bytes(keyAES)));
+		return res;
+	} else{
+		const encryptedBytes = Base64Util.decode(dataString);
+		const enCodeFormat = keyAES.toByteArray();
+		const secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
+		const cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+		cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
+		
+		const result = cipher.doFinal(encryptedBytes);
+		
+		return String(result);
+	}
+}
+
+// SHA1加密
+export const sha1Sync : CommonSync = function (str : string) : string {
+	const res : string = SHAUtil.stringSHA(str, SHAUtil.SHA1);
+	return res;
+}
+
+// SHA256加密
+export const sha256Sync : CommonSync = function (str : string) : string {
+	const res : string = SHAUtil.stringSHA(str, SHAUtil.SHA256);
+	return res;
+}
+
+// SM2非对称加密密钥
+export const sm2KeyPair  = function () : string[] {
+	let arr: Array<string> = [];
+	const dom = SM2Util.generateKeyPair();
+	arr.push(Util.byte2HexStr(dom[0]))
+	arr.push(Util.byte2HexStr(dom[1]))
+	return arr;
+}
+// 国产SM2非对称公钥加密
+export const sm2EncryptSync : sm4Sync = function (dataString : string, publicKey : string) : string {
+	const encryptByPublicKey = SM2Util.encrypt(Util.hexStr2Bytes(publicKey), dataString.toByteArray());
+	return Util.byte2HexStr(encryptByPublicKey);
+}
+// 国产SM2非对称私钥解密
+export const sm2DecryptSync : sm4Sync = function (dataString : string, privateKey : string) : string {
+	return String(SM2Util.decrypt(Util.hexStr2Bytes(privateKey), Util.hexStr2Bytes(dataString)));
+}
+// sm2签名
+export const sm2PubSignSync : sm4Sync = function (dataString : string, privateKey : string) : string {
+	const sign = SM2Util.sign(Util.hexStr2Bytes(privateKey), Util.hexStr2Bytes(dataString));
+	return Util.byte2HexStr(sign);
+}
+// sm2验签
+export const sm2PubSignValSync : sm2Validate = function (dataString : string, publicKey : string, sign : string) : boolean {
+	const verifySign = SM2Util.verifySign(Util.hexStr2Bytes(publicKey), Util.hexStr2Bytes(dataString), Util.hexStr2Bytes(sign));
+	return verifySign;
+}
+
+// 国产SM3加密
+export const sm3EncryptSync : CommonSync = function (dataString : string) : string {
+	const res : string = SM3Util.encryptInner(dataString);
+	return res;
+}
+
+// 国产SM4CBC加密
+export const sm4CBCEncryptSync : ivSync = function (dataString : string, keySM4 : string, iv: string) : string {
+	const res : string = Util.byte2HexStr(SM4Util.encrypt(dataString.toByteArray(), Util.hexStr2Bytes(keySM4), SM4Util.SM4_CBC_PKCS5, Util.hexStr2Bytes(iv)))
+	return res;
+}
+
+// 国产SM4ECB加密
+export const sm4ECBEncryptSync : sm4Sync = function (dataString : string, keySM4 : string) : string {
+	const res : string = Util.byte2HexStr(SM4Util.encrypt(dataString.toByteArray(), Util.hexStr2Bytes(keySM4), SM4Util.SM4_ECB_PKCS5, null))
+	return res;
+}
+
+// 国产SM4CBC解密
+export const sm4CBCDecryptSync : ivSync = function (dataString : string, keySM4 : string, iv: string) : string {
+	const res : string = String(SM4Util.decrypt(Util.hexStr2Bytes(dataString), Util.hexStr2Bytes(keySM4), SM4Util.SM4_CBC_PKCS5, Util.hexStr2Bytes(iv)))
+	return res;
+}
+
+// 国产SM4ECB解密
+export const sm4ECBDecryptSync : sm4Sync = function (dataString : string, keySM4 : string) : string {
+	const res : string = String(SM4Util.decrypt(Util.hexStr2Bytes(dataString), Util.hexStr2Bytes(keySM4), SM4Util.SM4_ECB_PKCS5, null))
+	return res;
+}
+
+// RSA非对称加密
+export const getKeyPair = function () : KeyPair {
+	return RSAUtil.generateRSAKeyPair();
+}
+// 生成KeyPair密钥
+export function generateKeyPair(pubStr:string,privateStr:string): KeyPair{
+	const publicKey = RSAUtil.getPublicKey(Util.hexStr2Bytes(pubStr))
+	const privateKey = RSAUtil.getPrivateKey(Util.hexStr2Bytes(privateStr))
+	return KeyPair(publicKey,privateKey)
+}
+
+export const rsaEncryptSync : rsaSync = function (dataString : string, keyPair : KeyPair, type : KeyType) : string {
+	let res : string;
+	if (type === KeyType.PUB) {
+		res = Util.byte2HexStr(RSAUtil.encryptByPublicKey(dataString.toByteArray(), keyPair.public))
+	} else {
+		res = Util.byte2HexStr(RSAUtil.encryptByPrivateKey(dataString.toByteArray(), keyPair.private))
+	}
+	return res;
+}
+// RSA非对称解密
+export const rsaDecryptSync : rsaSync = function (dataString : string, keyPair : KeyPair, type : KeyType) : string {
+	let res : string;
+	if (type === KeyType.PUB) {
+		res = String(RSAUtil.decryptByPublicKeyKey(Util.hexStr2Bytes(dataString), keyPair.public))
+	} else {
+		res = String(RSAUtil.decryptByPrivateKey(Util.hexStr2Bytes(dataString), keyPair.private))
+	}
+	return res;
+}
+
+// RSA SHA256签名
+export const rsaSHA256PrivateSync : rsaCommonSync = function (dataString : string, keyPair : KeyPair) : string {
+	const res : string = Util.byte2HexStr(RSAUtil.signWithSHA256(dataString.toByteArray(), keyPair.private))
+	return res;
+}
+
+// RSA MD5签名
+export const rsaMD5PrivateSync : rsaCommonSync = function (dataString : string, keyPair : KeyPair) : string {
+	const res : string = Util.byte2HexStr(RSAUtil.signWithMD5(dataString.toByteArray(), keyPair.private))
+	return res;
+}
+
+// RSA SHA256签名验签
+export const rsaSHA256PubValSync : rsaValidate = function (dataString : string,result: string, keyPair : KeyPair) : boolean {
+	const res : boolean = RSAUtil.verifySignWithSHA256(dataString.toByteArray(),Util.hexStr2Bytes(result), keyPair.public)
+	return res;
+}
+
+// RSA MD5签名验签
+export const rsaMD5PubValSync : rsaValidate = function (dataString : string,result: string, keyPair : KeyPair) : boolean {
+	const res : boolean = RSAUtil.verifySignWithMD5(dataString.toByteArray(),Util.hexStr2Bytes(result), keyPair.public)
+	return res;
+}
+
+// AES CBC对称加密
+export const aesCBCEncryptSync : ivSync = function (dataString : string, key : string, iv: string) : string {
+	const byteContent = dataString.toByteArray();
+	const enCodeFormat = key.toByteArray();
+	const secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
+	const initParam = iv.toByteArray();
+	const ivParameterSpec = new IvParameterSpec(initParam);
+	const cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+	cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
+	
+	const encryptedBytes = cipher.doFinal(byteContent);
+	
+	// 同样对加密后数据进行 base64 编码
+	return Base64Util.encode(encryptedBytes);
+}
+
+// AES CBC对称解密
+export const aesCBCDecryptSync : ivSync = function (dataString : string, key : string, iv: string) : string {
+	const encryptedBytes = Base64Util.decode(dataString);
+	const enCodeFormat = key.toByteArray();
+	const secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
+	const initParam = iv.toByteArray();
+	const ivParameterSpec = new IvParameterSpec(initParam);
+	const cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+	cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
+	
+	const result = cipher.doFinal(encryptedBytes);
+	
+	return String(result);
+}
+
+// hmacSHA1加密
+export const hmacSHA1Sync : sm4Sync = function (plaintext : string, key : string) : string {
+	const byteContent = plaintext.toByteArray();
+	const enCodeFormat = key.toByteArray();
+	const secretKeySpec = new SecretKeySpec(enCodeFormat, "HmacSHA1");
+	const mac = Mac.getInstance("HmacSHA1");
+	mac.init(secretKeySpec);
+	const hmacBytes = mac.doFinal(byteContent);
+	return Util.byte2HexStr(hmacBytes)
+}

BIN
uni_modules/tq-encrypt/utssdk/app-ios/Resources/GMObjC.bundle/Info.plist


+ 14 - 0
uni_modules/tq-encrypt/utssdk/app-ios/Resources/GMObjC.bundle/PrivacyInfo.xcprivacy

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>NSPrivacyTracking</key>
+	<false/>
+	<key>NSPrivacyAccessedAPITypes</key>
+	<array/>
+	<key>NSPrivacyCollectedDataTypes</key>
+	<array/>
+	<key>NSPrivacyTrackingDomains</key>
+	<array/>
+</dict>
+</plist>

+ 234 - 0
uni_modules/tq-encrypt/utssdk/app-ios/Resources/_CodeSignature/CodeResources

@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>files</key>
+	<dict>
+		<key>GMObjC.bundle/Info.plist</key>
+		<data>
+		17PAwlX/7lcXWGkNMZtCjOjN/zg=
+		</data>
+		<key>GMObjC.bundle/PrivacyInfo.xcprivacy</key>
+		<data>
+		F6mYXr6EQZyLKcQNM0vmTGcGMns=
+		</data>
+		<key>Headers/unimoduleTqEncrypt-Swift.h</key>
+		<data>
+		DrrYhL/jZONqJ8wfwb+8gn8/wvk=
+		</data>
+		<key>Headers/unimoduleTqEncrypt.h</key>
+		<data>
+		FH2SRnQAHIO8AbDZPa5/Bz/CcdA=
+		</data>
+		<key>Info.plist</key>
+		<data>
+		r41ktVIrvPZcbYlkcNTrYuN3Df4=
+		</data>
+		<key>Modules/module.modulemap</key>
+		<data>
+		sKVKsHgxK0+G8CqI/BMBFd2Fn80=
+		</data>
+		<key>Modules/unimoduleTqEncrypt.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo</key>
+		<data>
+		8fvVeTjCxB1CHWB4bn+bV1QIf/s=
+		</data>
+		<key>Modules/unimoduleTqEncrypt.swiftmodule/x86_64-apple-ios-simulator.abi.json</key>
+		<data>
+		3OcBUVG1FuGfFUmNpQe2qsxepVs=
+		</data>
+		<key>Modules/unimoduleTqEncrypt.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface</key>
+		<data>
+		ZPvCeNpyoei3QfbzOaVfcc+P0WA=
+		</data>
+		<key>Modules/unimoduleTqEncrypt.swiftmodule/x86_64-apple-ios-simulator.swiftdoc</key>
+		<data>
+		nsDzmyCGrNxw2NUYCv7M4Wc/8Eo=
+		</data>
+		<key>Modules/unimoduleTqEncrypt.swiftmodule/x86_64-apple-ios-simulator.swiftinterface</key>
+		<data>
+		ZPvCeNpyoei3QfbzOaVfcc+P0WA=
+		</data>
+		<key>Modules/unimoduleTqEncrypt.swiftmodule/x86_64-apple-ios-simulator.swiftmodule</key>
+		<data>
+		00UdxXysbIw5buY8/HiYAGQEbxE=
+		</data>
+		<key>config.json</key>
+		<data>
+		42J1X+tVFlou+JsNQziJVYpabU4=
+		</data>
+	</dict>
+	<key>files2</key>
+	<dict>
+		<key>GMObjC.bundle/Info.plist</key>
+		<dict>
+			<key>hash2</key>
+			<data>
+			Jhq1+Ut7CwZ0hcK0iCY9ofHmTqTyBiLtcTINK2Mgw6Y=
+			</data>
+		</dict>
+		<key>GMObjC.bundle/PrivacyInfo.xcprivacy</key>
+		<dict>
+			<key>hash2</key>
+			<data>
+			oHQY5f4SjiJM03lkvCHFA7eqL1dee0knRoR4rYcyFP4=
+			</data>
+		</dict>
+		<key>Headers/unimoduleTqEncrypt-Swift.h</key>
+		<dict>
+			<key>hash2</key>
+			<data>
+			zKa0BBB/GRAg+Xhu7RLW3CNn3m5QIvQtAwYEvVAdK6I=
+			</data>
+		</dict>
+		<key>Headers/unimoduleTqEncrypt.h</key>
+		<dict>
+			<key>hash2</key>
+			<data>
+			XAsze1m7Z4PhyI2gj+RafZVS4xyqWjgvqraTawdVPMY=
+			</data>
+		</dict>
+		<key>Modules/module.modulemap</key>
+		<dict>
+			<key>hash2</key>
+			<data>
+			5JyZ91/h4xPf9/57Qe6uGkV0R5WlFoF1Sd7NslkG52M=
+			</data>
+		</dict>
+		<key>Modules/unimoduleTqEncrypt.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo</key>
+		<dict>
+			<key>hash2</key>
+			<data>
+			CwBd4DQIuM5bwPJZJS3UKQooLaMziEJhI7t54vHPDWQ=
+			</data>
+		</dict>
+		<key>Modules/unimoduleTqEncrypt.swiftmodule/x86_64-apple-ios-simulator.abi.json</key>
+		<dict>
+			<key>hash2</key>
+			<data>
+			mKERTv08MC7E5LO5mxnO4aRlY63JJewZMa6q5DvscyE=
+			</data>
+		</dict>
+		<key>Modules/unimoduleTqEncrypt.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface</key>
+		<dict>
+			<key>hash2</key>
+			<data>
+			xnccLpGUIzoI2KqPY5ZUbqodAD1DLJA5AJ2j9x/Xvc8=
+			</data>
+		</dict>
+		<key>Modules/unimoduleTqEncrypt.swiftmodule/x86_64-apple-ios-simulator.swiftdoc</key>
+		<dict>
+			<key>hash2</key>
+			<data>
+			UGc8AkteVYRwNxyrY7gPG3ZrKOuBikPZ6fS8HhCuzMk=
+			</data>
+		</dict>
+		<key>Modules/unimoduleTqEncrypt.swiftmodule/x86_64-apple-ios-simulator.swiftinterface</key>
+		<dict>
+			<key>hash2</key>
+			<data>
+			xnccLpGUIzoI2KqPY5ZUbqodAD1DLJA5AJ2j9x/Xvc8=
+			</data>
+		</dict>
+		<key>Modules/unimoduleTqEncrypt.swiftmodule/x86_64-apple-ios-simulator.swiftmodule</key>
+		<dict>
+			<key>hash2</key>
+			<data>
+			8HBT3hsbCDIvH4AaJf9zZMWzcryX7I857bcUVSXoVa4=
+			</data>
+		</dict>
+		<key>config.json</key>
+		<dict>
+			<key>hash2</key>
+			<data>
+			Rs+kXZDGrkolFltWOyksgUdxySSs9OgAQ+MSF7L2KoU=
+			</data>
+		</dict>
+	</dict>
+	<key>rules</key>
+	<dict>
+		<key>^.*</key>
+		<true/>
+		<key>^.*\.lproj/</key>
+		<dict>
+			<key>optional</key>
+			<true/>
+			<key>weight</key>
+			<real>1000</real>
+		</dict>
+		<key>^.*\.lproj/locversion.plist$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>1100</real>
+		</dict>
+		<key>^Base\.lproj/</key>
+		<dict>
+			<key>weight</key>
+			<real>1010</real>
+		</dict>
+		<key>^version.plist$</key>
+		<true/>
+	</dict>
+	<key>rules2</key>
+	<dict>
+		<key>.*\.dSYM($|/)</key>
+		<dict>
+			<key>weight</key>
+			<real>11</real>
+		</dict>
+		<key>^(.*/)?\.DS_Store$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>2000</real>
+		</dict>
+		<key>^.*</key>
+		<true/>
+		<key>^.*\.lproj/</key>
+		<dict>
+			<key>optional</key>
+			<true/>
+			<key>weight</key>
+			<real>1000</real>
+		</dict>
+		<key>^.*\.lproj/locversion.plist$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>1100</real>
+		</dict>
+		<key>^Base\.lproj/</key>
+		<dict>
+			<key>weight</key>
+			<real>1010</real>
+		</dict>
+		<key>^Info\.plist$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>20</real>
+		</dict>
+		<key>^PkgInfo$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>20</real>
+		</dict>
+		<key>^embedded\.provisionprofile$</key>
+		<dict>
+			<key>weight</key>
+			<real>20</real>
+		</dict>
+		<key>^version\.plist$</key>
+		<dict>
+			<key>weight</key>
+			<real>20</real>
+		</dict>
+	</dict>
+</dict>
+</plist>

+ 21 - 0
uni_modules/tq-encrypt/utssdk/app-ios/config.json

@@ -0,0 +1,21 @@
+{
+	"deploymentTarget": "13",
+	"dependencies-pods": [
+		{
+			"name": "CryptoSwift",
+			"version": "~> 1.8.2"
+		},
+		{
+			"name": "GMObjC",
+			"version": "3.3.8"
+		},
+		{
+			"name": "GMOpenSSL",
+			"version": "2.2.9"
+		},
+		{
+			"name": "SwiftyRSA",
+			"version": "1.7.0"
+		}
+	]
+}

+ 237 - 0
uni_modules/tq-encrypt/utssdk/app-ios/index.uts

@@ -0,0 +1,237 @@
+import { CommonSync, sm4Sync,ivSync,sm2Validate } from '../interface.uts';
+import { Insecure, SHA256 } from 'CryptoKit';
+import { AES, ECB, CBC } from "CryptoSwift";
+import { GMSm3Utils, GMSm4Utils, GMSm2Utils } from "GMObjC";
+import { PublicKey, ClearMessage, EncryptedMessage } from "SwiftyRSA";
+
+// md5加密
+export const md5Sync : CommonSync = function (md5Str : string) : string {
+	let data = md5Str.data(using = String.Encoding.utf8)!
+	let MD5Digest = Insecure.MD5.hash(data = data)
+	let ht = MD5Digest.map((x : UInt8) : String => {
+		let str = String(format = "%02hhx", x)
+		if (str != nil) {
+			return str;
+		} else {
+			return "";
+		}
+	})
+	return ht.join('');
+}
+
+// base64加密
+export const base64EncodeSync : CommonSync = function (str : string) : string {
+	const originalData = str.data(using = String.Encoding.utf8)!
+	const base64EncodedString = originalData.base64EncodedString()
+	return base64EncodedString;
+}
+
+// base64解密
+export const base64DecodeSync : CommonSync = function (str : string) : string {
+	let decodedData = Data(base64Encoded = str)!
+	if (decodedData != nil) {
+		let originalString = String(data = decodedData, encoding = String.Encoding.utf8)!
+		if (originalString != nil) {
+			return originalString
+		} else {
+			return "";
+		}
+	} else {
+		return "";
+	}
+}
+
+// SHA1加密
+export const sha1Sync : CommonSync = function (str : string) : string {
+	let data = str.data(using = String.Encoding.utf8)!
+	let SHA1Digest = Insecure.SHA1.hash(data = data)
+	let ht = SHA1Digest.map((x : UInt8) : String => {
+		let str = String(format = "%02hhx", x)
+		if (str != nil) {
+			return str;
+		} else {
+			return "";
+		}
+	})
+	return ht.join('');
+}
+
+// SHA256加密
+export const sha256Sync : CommonSync = function (str : string) : string {
+	let data = str.data(using = String.Encoding.utf8)!
+	let SHA256Digest = SHA256.hash(data = data)
+	let ht = SHA256Digest.map((x : UInt8) : String => {
+		let str = String(format = "%02hhx", x)
+		if (str != nil) {
+			return str;
+		} else {
+			return "";
+		}
+	})
+	return ht.join('');
+}
+
+// AES对称加密
+export const aesEncryptSync : sm4Sync = function (plainText : string, key : string) : string {
+	let keyData = key.data(using = String.Encoding.utf8)!
+	let plainTextData = plainText.data(using = String.Encoding.utf8)!
+	try {
+		let aes = UTSiOS.try(AES(key = keyData.bytes, blockMode = ECB(), padding = Padding.pkcs7))
+		// 开始加密
+		let encrypted = UTSiOS.try(aes.encrypt(plainTextData.bytes))
+		// 将加密结果转成base64形式
+		return encrypted.toBase64()
+	} catch (e) {
+		console.log(e);
+		return "";
+	}
+}
+
+// AES对称解密
+export const aesDecryptSync : sm4Sync = function (encryptedBase64 : string, key : string) : string {
+	let keyData = key.data(using = String.Encoding.utf8)!
+
+	try {
+		let encryptedData = Data(base64Encoded = encryptedBase64)!
+		let aes = UTSiOS.try(AES(key = keyData.bytes, blockMode = ECB(), padding = Padding.pkcs7))
+		// 开始加密
+		let decryptedBytes = UTSiOS.try(aes.decrypt(encryptedData.bytes))
+		let decryptedData = Data(decryptedBytes)
+		let decryptedString = String(data = decryptedData, encoding = String.Encoding.utf8)!
+		if (decryptedString != nil) {
+			return decryptedString
+		} else{
+			return "";
+		}
+	} catch (e) {
+		console.log(e);
+		return "";
+	}
+}
+
+// 国产SM3加密
+export const sm3EncryptSync : CommonSync = function (dataString : string) : string {
+	let plainData = dataString.data(using = String.Encoding.utf8)!
+	let res = GMSm3Utils.hash(with = plainData)!
+	return res;
+}
+
+// 国产SM4ECB加密
+export const sm4ECBEncryptSync : sm4Sync = function (dataString : string, keySM4 : string) : string {
+	let res = GMSm4Utils.ecbEncryptText(dataString,key=keySM4)!
+	return res;
+}
+
+// 国产SM4ECB解密
+export const sm4ECBDecryptSync : sm4Sync = function (dataString : string, keySM4 : string) : string {
+	let res = GMSm4Utils.ecbDecryptText(dataString,key=keySM4)!
+	return res;
+}
+
+// 国产SM4CBC加密
+export const sm4CBCEncryptSync : ivSync = function (dataString : string, keySM4 : string, iv: string) : string {
+	let res = GMSm4Utils.cbcEncryptText(dataString,key=keySM4,iv=iv)!
+	return res;
+}
+
+// 国产SM4CBC解密
+export const sm4CBCDecryptSync : ivSync = function (dataString : string, keySM4 : string, iv: string) : string {
+	let res = GMSm4Utils.cbcDecryptText(dataString,key=keySM4,iv=iv)!
+	return res;
+}
+
+// 国产SM2非对称公钥加密
+export const sm2EncryptSync : sm4Sync = function (dataString : string, publicKey : string) : string {
+	let res = GMSm2Utils.encryptText(dataString,publicKey=publicKey)!
+	return res;
+}
+
+// 国产SM2非对称私钥解密
+export const sm2DecryptSync : sm4Sync = function (dataString : string, privateKey : string) : string {
+	let res = GMSm2Utils.decrypt(toText=dataString,privateKey=privateKey)!
+	return res;
+}
+
+// sm2签名
+export const sm2PubSignSync : sm4Sync = function (dataString : string, privateKey : string) : string {
+	const sign = GMSm2Utils.signText(dataString, privateKey=privateKey, userID=nil)!;
+	return sign;
+}
+// sm2验签
+export const sm2PubSignValSync : sm2Validate = function (dataString : string, publicKey : string, sign : string) : boolean {
+	const verifySign = GMSm2Utils.verifyText(dataString, signRS=sign, publicKey=publicKey, userID=nil);
+	return verifySign;
+}
+
+// hmacSHA1加密
+export const hmacSHA1Sync : sm4Sync = function (plaintext : string, key : string) : string {
+	let res = GMSm3Utils.hmac(GMHashType.SHA1 ,key=key,plaintext=plaintext)!
+	return res;
+}
+
+// AES CBC对称加密
+export const aesCBCEncryptSync : ivSync = function (plainText : string, key : string, iv: string) : string {
+	let keyData = key.data(using = String.Encoding.utf8)!
+	let ivData = iv.data(using = String.Encoding.utf8)!
+	let plainTextData = plainText.data(using = String.Encoding.utf8)!
+	try {
+		let aes = UTSiOS.try(AES(key = keyData.bytes, blockMode = CBC(iv=ivData.bytes), padding = Padding.pkcs7))
+		// 开始加密
+		let encrypted = UTSiOS.try(aes.encrypt(plainTextData.bytes))
+		// 将加密结果转成base64形式
+		return encrypted.toBase64()
+	} catch (e) {
+		console.log(e);
+		return "";
+	}
+}
+
+// AES CBC对称解密
+export const aesCBCDecryptSync : ivSync = function (encryptedBase64 : string, key : string, iv: string) : string {
+	let keyData = key.data(using = String.Encoding.utf8)!
+	let ivData = iv.data(using = String.Encoding.utf8)!
+	
+	try {
+		let encryptedData = Data(base64Encoded = encryptedBase64)!
+		let aes = UTSiOS.try(AES(key = keyData.bytes, blockMode = CBC(iv=ivData.bytes), padding = Padding.pkcs7))
+		// 开始加密
+		let decryptedBytes = UTSiOS.try(aes.decrypt(encryptedData.bytes))
+		let decryptedData = Data(decryptedBytes)
+		let decryptedString = String(data = decryptedData, encoding = String.Encoding.utf8)!
+		if (decryptedString != nil) {
+			return decryptedString
+		} else{
+			return "";
+		}
+	} catch (e) {
+		console.log(e);
+		return "";
+	}
+}
+
+// RSA非对称加密
+export const rsaEncryptSync : sm4Sync = function (dataString : string, publicStr: string) : string {
+	try {
+		let publicKey = UTSiOS.try(PublicKey(pemEncoded = publicStr))
+		let clear = UTSiOS.try(ClearMessage(string = dataString, using = String.Encoding.utf8))
+		let encrypted = UTSiOS.try(clear.encrypted(with = publicKey, padding = Padding.PKCS1))
+		return encrypted.base64String
+	} catch (e) {
+		console.log(e);
+		return "";
+	}
+}
+
+// RSA非对称解密
+export const rsaDecryptSync : sm4Sync = function (dataString : string, privateStr: string) : string {
+	try {
+		let privateKey = UTSiOS.try(PrivateKey(pemEncoded = privateStr))
+		let encrypted = UTSiOS.try(EncryptedMessage(base64Encoded = dataString))
+		let clear = UTSiOS.try(encrypted.decrypted(with = privateKey, padding = Padding.PKCS1))
+		let base64String = clear.base64String
+		return base64DecodeSync(base64String)
+	} catch (e) {
+		console.log(e);
+		return "";
+	}
+}

+ 23 - 0
uni_modules/tq-encrypt/utssdk/interface.uts

@@ -0,0 +1,23 @@
+/* 同步函数定义 */
+export type CommonSync = (str : string) => string
+
+export type sm4Sync = (str : string, key : string) => string
+
+export type ivSync = (str : string, key : string, iv: string) => string
+
+export type sm2Validate = (str : string, pub : string, sign: string) => boolean
+
+// #ifdef APP-ANDROID
+import KeyPair from 'java.security.KeyPair';
+export enum KeyType {
+	PUB = 1,
+	PRI = 2
+}
+
+export type rsaSync = (str : string, key : KeyPair, type : KeyType) => string
+
+export type rsaCommonSync = (str : string, key : KeyPair) => string
+
+export type rsaValidate = (str : string, str2 : string, key : KeyPair) => boolean
+
+// #endif

+ 1 - 0
uni_modules/tq-encrypt/utssdk/web/index.uts

@@ -0,0 +1 @@
+export * from '../../common/index';

+ 228 - 0
utils/crypto.uts

@@ -20,6 +20,11 @@ export const encryptAES = (word: string): string => {
     // #ifdef APP-HARMONY
     return encryptAESHarmony(word, KEY_STR, IV_STR)
     // #endif
+	
+ // #ifdef APP-IOS
+	return encryptAESiOS(word, KEY_STR, IV_STR)
+	// #endif
+	    
     
     // #ifdef WEB
     return encryptAESWeb(word, KEY_STR, IV_STR)
@@ -39,12 +44,18 @@ export const encryptAES = (word: string): string => {
  */
 export const decryptAES = (word: string): string => {
     // #ifdef APP-ANDROID
+	console.warn('APP-ANDROID')
     return decryptAESAndroid(word, KEY_STR, IV_STR)
     // #endif
     
     // #ifdef APP-HARMONY
+	console.warn('APP-HARMONY')
     return decryptAESHarmony(word, KEY_STR, IV_STR)
     // #endif
+	
+	// #ifdef APP-IOS
+	return decryptAESiOS(word, KEY_STR, IV_STR)
+	// #endif
     
     // #ifdef WEB
     return decryptAESWeb(word, KEY_STR, IV_STR)
@@ -123,6 +134,223 @@ function decryptAESAndroid(cipherText: string, keyStr: string, ivStr: string): s
 }
 // #endif
 
+
+// ============ iOS 平台实现 ============
+// #ifdef APP-IOS
+
+/**
+ * iOS 平台 AES 加密实现
+ */
+function encryptAESiOS(plainText: string, keyStr: string, ivStr: string): string {
+    try {
+        // 将字符串转为 Data
+        const plainData = NSString.stringWithString(plainText).dataUsingEncoding(NSUTF8StringEncoding)
+        const keyData = NSString.stringWithString(keyStr).dataUsingEncoding(NSUTF8StringEncoding)
+        const ivData = NSString.stringWithString(ivStr).dataUsingEncoding(NSUTF8StringEncoding)
+        
+        if (!plainData || !keyData || !ivData) {
+            console.error('AES 加密失败:数据转换错误')
+            return plainText
+        }
+        
+        // 准备加密参数
+        const keyBytes = keyData.bytes
+        const ivBytes = ivData.bytes
+        const plainBytes = plainData.bytes
+        const plainLength = plainData.length
+        
+        // 计算加密后数据大小
+        const blockSize = 16  // AES 块大小
+        const bufferSize = Math.floor((plainLength + blockSize) / blockSize) * blockSize
+        const buffer = new interop.Pointer(bufferSize)
+        
+        // 执行加密
+        let encryptedLength = 0
+        const status = CCCrypt(
+            0, // kCCEncrypt
+            0, // kCCAlgorithmAES
+            0x0001, // kCCOptionPKCS7Padding
+            keyBytes,
+            keyData.length,
+            ivBytes,
+            plainBytes,
+            plainLength,
+            buffer,
+            bufferSize,
+            encryptedLength
+        )
+        
+        if (status !== 0) { // kCCSuccess
+            console.error('AES 加密失败,状态码:', status)
+            return plainText
+        }
+        
+        // 转为 Base64
+        const encryptedData = NSData.dataWithBytesLength(buffer, encryptedLength)
+        const base64String = encryptedData.base64EncodedStringWithOptions(0)
+        
+        return base64String.toString()
+    } catch (e) {
+        console.error('AES 加密失败(iOS)', e)
+        return plainText
+    }
+}
+
+/**
+ * iOS 平台 AES 解密实现
+ */
+function decryptAESiOS(cipherText: string, keyStr: string, ivStr: string): string {
+    try {
+        // Base64 字符串转为 Data
+        const cipherData = NSData.alloc().initWithBase64EncodedStringOptions(cipherText, 0)
+        const keyData = NSString.stringWithString(keyStr).dataUsingEncoding(NSUTF8StringEncoding)
+        const ivData = NSString.stringWithString(ivStr).dataUsingEncoding(NSUTF8StringEncoding)
+        
+        if (!cipherData || !keyData || !ivData) {
+            console.error('AES 解密失败:数据转换错误')
+            return cipherText
+        }
+        
+        // 准备解密参数
+        const keyBytes = keyData.bytes
+        const ivBytes = ivData.bytes
+        const cipherBytes = cipherData.bytes
+        const cipherLength = cipherData.length
+        
+        // 计算解密后数据大小
+        const bufferSize = cipherLength + 16  // 预留空间
+        const buffer = new interop.Pointer(bufferSize)
+        
+        // 执行解密
+        let decryptedLength = 0
+        const status = CCCrypt(
+            1, // kCCDecrypt
+            0, // kCCAlgorithmAES
+            0x0001, // kCCOptionPKCS7Padding
+            keyBytes,
+            keyData.length,
+            ivBytes,
+            cipherBytes,
+            cipherLength,
+            buffer,
+            bufferSize,
+            decryptedLength
+        )
+        
+        if (status !== 0) { // kCCSuccess
+            console.error('AES 解密失败,状态码:', status)
+            return cipherText
+        }
+        
+        // 转为字符串
+        const decryptedData = NSData.dataWithBytesLength(buffer, decryptedLength)
+        const decryptedStr = NSString.alloc().initWithDataEncoding(decryptedData, NSUTF8StringEncoding)
+        
+        return decryptedStr.toString()
+    } catch (e) {
+        console.error('AES 解密失败(iOS)', e)
+        return cipherText
+    }
+}
+
+// iOS 加密常量定义
+declare const CCCrypt: any
+declare const NSData: any
+declare const NSString: any
+declare const NSUTF8StringEncoding: any
+declare const interop: any
+
+// 或者更简洁的 iOS 实现版本(使用 CryptoKit)
+function encryptAESiOS_simple(plainText: string, keyStr: string, ivStr: string): string {
+    try {
+        // 使用 CommonCrypto
+        const plainData = plainText.toNSData()
+        const keyData = keyStr.toNSData()
+        const ivData = ivStr.toNSData()
+        
+        // 创建加密上下文
+        const cryptor = NSMutableData.dataWithLength(plainData.length + 16)
+        let dataOutMoved = 0
+        
+        const status = CCCrypt(
+            0, // kCCEncrypt
+            0, // kCCAlgorithmAES128
+            1, // kCCOptionPKCS7Padding
+            keyData.bytes,
+            keyData.length,
+            ivData.bytes,
+            plainData.bytes,
+            plainData.length,
+            cryptor.mutableBytes,
+            cryptor.length,
+            dataOutMoved
+        )
+        
+        if (status === 0) { // kCCSuccess
+            cryptor.length = dataOutMoved
+            return cryptor.base64EncodedStringWithOptions(0)
+        } else {
+            console.error('加密失败,错误码:', status)
+            return plainText
+        }
+    } catch (e) {
+        console.error('AES 加密失败(iOS)', e)
+        return plainText
+    }
+}
+
+function decryptAESiOS_simple(cipherText: string, keyStr: string, ivStr: string): string {
+    try {
+        // Base64 解码
+        const cipherData = NSData.alloc().initWithBase64EncodedStringOptions(cipherText, 0)
+        const keyData = keyStr.toNSData()
+        const ivData = ivStr.toNSData()
+        
+        // 创建解密上下文
+        const cryptor = NSMutableData.dataWithLength(cipherData.length + 16)
+        let dataOutMoved = 0
+        
+        const status = CCCrypt(
+            1, // kCCDecrypt
+            0, // kCCAlgorithmAES128
+            1, // kCCOptionPKCS7Padding
+            keyData.bytes,
+            keyData.length,
+            ivData.bytes,
+            cipherData.bytes,
+            cipherData.length,
+            cryptor.mutableBytes,
+            cryptor.length,
+            dataOutMoved
+        )
+        
+        if (status === 0) { // kCCSuccess
+            cryptor.length = dataOutMoved
+            return NSString.alloc().initWithDataEncoding(cryptor, NSUTF8StringEncoding)
+        } else {
+            console.error('解密失败,错误码:', status)
+            return cipherText
+        }
+    } catch (e) {
+        console.error('AES 解密失败(iOS)', e)
+        return cipherText
+    }
+}
+
+// 扩展 String 类型以添加 toNSData 方法
+declare global {
+    interface String {
+        toNSData(): any
+    }
+}
+
+// 为 String 添加 toNSData 方法
+String.prototype.toNSData = function(): any {
+    return NSString.stringWithString(this).dataUsingEncoding(NSUTF8StringEncoding)
+}
+// #endif
+
+
 // 鸿蒙平台 AES 加密实现
 // #ifdef APP-HARMONY
 

+ 2 - 2
utils/request.uts

@@ -13,8 +13,8 @@ export type RequestConfig = {
 };
 
 // 基础 URL
-// const BASE_URL = "http://192.168.110.105:8080";
-const BASE_URL = "http://222.243.138.146:5095";
+const BASE_URL = "http://192.168.110.105:8080";
+// const BASE_URL = "http://222.243.138.146:5095";
 // const BASE_URL = "http://10.170.129.135:8089";
 
 /**

+ 15 - 0
utils/storage.uts

@@ -6,6 +6,7 @@ import { encryptAES, decryptAES } from './crypto'
 const ACCESS_TOKEN_KEY = "access_token"
 const USER_INFO_KEY = "user_info"
 const REMEMBERED_ACCOUNT_KEY = "remembered_account"
+const IS_KEY = "is_key"
 
 /**
  * 保存 AccessToken
@@ -136,3 +137,17 @@ export const checkPermi = (value: string[]): boolean => {
   }
 }
 
+export const saveStoreIsKey = (isKey:string): void => {
+    uni.setStorageSync(IS_KEY, isKey)
+}
+
+export const getStoreIsKey = (): string | null => {
+	const isKey = uni.getStorageSync(IS_KEY)
+	if (isKey != null) {
+	    const isKeyStr = isKey as string
+	    if (isKeyStr.length > 0) {
+	        return isKeyStr
+	    }
+	}
+	return null
+}