|
|
@@ -4,8 +4,8 @@
|
|
|
*/
|
|
|
|
|
|
// 加密密钥和 IV(与后端保持一致)
|
|
|
-const KEY_STR = 'richwaykey000000'
|
|
|
-const IV_STR = 'richway-iv000000'
|
|
|
+const KEY_STR = 'ygtxgxtkey030206'
|
|
|
+const IV_STR = 'ygtxgxt-iv030206'
|
|
|
|
|
|
/**
|
|
|
* AES 加密
|
|
|
@@ -134,7 +134,6 @@ function decryptAESAndroid(cipherText: string, keyStr: string, ivStr: string): s
|
|
|
}
|
|
|
// #endif
|
|
|
|
|
|
-
|
|
|
// ============ iOS 平台实现 ============
|
|
|
// #ifdef APP-IOS
|
|
|
|
|
|
@@ -143,10 +142,10 @@ function decryptAESAndroid(cipherText: string, keyStr: string, ivStr: string): s
|
|
|
*/
|
|
|
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)
|
|
|
+ // 使用 UTS 的 iOS 平台 API
|
|
|
+ const plainData = plainText.dataUsingEncoding(4) // NSUTF8StringEncoding = 4
|
|
|
+ const keyData = keyStr.dataUsingEncoding(4)
|
|
|
+ const ivData = ivStr.dataUsingEncoding(4)
|
|
|
|
|
|
if (!plainData || !keyData || !ivData) {
|
|
|
console.error('AES 加密失败:数据转换错误')
|
|
|
@@ -162,34 +161,38 @@ function encryptAESiOS(plainText: string, keyStr: string, ivStr: string): string
|
|
|
// 计算加密后数据大小
|
|
|
const blockSize = 16 // AES 块大小
|
|
|
const bufferSize = Math.floor((plainLength + blockSize) / blockSize) * blockSize
|
|
|
- const buffer = new interop.Pointer(bufferSize)
|
|
|
+
|
|
|
+ // 创建输出缓冲区
|
|
|
+ const buffer = plus.ios.newObject('NSMutableData', 'dataWithLength:', bufferSize)
|
|
|
|
|
|
// 执行加密
|
|
|
- let encryptedLength = 0
|
|
|
- const status = CCCrypt(
|
|
|
- 0, // kCCEncrypt
|
|
|
- 0, // kCCAlgorithmAES
|
|
|
- 0x0001, // kCCOptionPKCS7Padding
|
|
|
+ let encryptedLength = plus.ios.newObject('NSUInteger')
|
|
|
+ const status = plus.ios.invoke('CCCrypt', ':',
|
|
|
+ 0, // kCCEncrypt = 0
|
|
|
+ 0, // kCCAlgorithmAES = 0
|
|
|
+ 0x0001, // kCCOptionPKCS7Padding = 0x0001
|
|
|
keyBytes,
|
|
|
keyData.length,
|
|
|
ivBytes,
|
|
|
plainBytes,
|
|
|
plainLength,
|
|
|
- buffer,
|
|
|
+ buffer.bytes,
|
|
|
bufferSize,
|
|
|
- encryptedLength
|
|
|
+ plus.ios.addrOf(encryptedLength)
|
|
|
)
|
|
|
|
|
|
- if (status !== 0) { // kCCSuccess
|
|
|
+ if (status !== 0) { // kCCSuccess = 0
|
|
|
console.error('AES 加密失败,状态码:', status)
|
|
|
return plainText
|
|
|
}
|
|
|
|
|
|
- // 转为 Base64
|
|
|
- const encryptedData = NSData.dataWithBytesLength(buffer, encryptedLength)
|
|
|
- const base64String = encryptedData.base64EncodedStringWithOptions(0)
|
|
|
+ // 设置实际数据长度
|
|
|
+ buffer.setLength(encryptedLength)
|
|
|
+
|
|
|
+ // 转为 Base64 字符串
|
|
|
+ const base64String = buffer.base64EncodedStringWithOptions(0)
|
|
|
|
|
|
- return base64String.toString()
|
|
|
+ return String(base64String)
|
|
|
} catch (e) {
|
|
|
console.error('AES 加密失败(iOS)', e)
|
|
|
return plainText
|
|
|
@@ -202,12 +205,19 @@ function encryptAESiOS(plainText: string, keyStr: string, ivStr: string): string
|
|
|
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)
|
|
|
+ const cipherData = plus.ios.invoke('NSData', 'alloc')
|
|
|
+ const initData = plus.ios.invoke(cipherData, 'initWithBase64EncodedString:options:', cipherText, 0)
|
|
|
+
|
|
|
+ if (!initData) {
|
|
|
+ console.error('AES 解密失败:Base64 解码失败')
|
|
|
+ return cipherText
|
|
|
+ }
|
|
|
|
|
|
- if (!cipherData || !keyData || !ivData) {
|
|
|
- console.error('AES 解密失败:数据转换错误')
|
|
|
+ const keyData = keyStr.dataUsingEncoding(4) // NSUTF8StringEncoding = 4
|
|
|
+ const ivData = ivStr.dataUsingEncoding(4)
|
|
|
+
|
|
|
+ if (!keyData || !ivData) {
|
|
|
+ console.error('AES 解密失败:密钥或 IV 转换错误')
|
|
|
return cipherText
|
|
|
}
|
|
|
|
|
|
@@ -217,62 +227,71 @@ function decryptAESiOS(cipherText: string, keyStr: string, ivStr: string): strin
|
|
|
const cipherBytes = cipherData.bytes
|
|
|
const cipherLength = cipherData.length
|
|
|
|
|
|
- // 计算解密后数据大小
|
|
|
- const bufferSize = cipherLength + 16 // 预留空间
|
|
|
- const buffer = new interop.Pointer(bufferSize)
|
|
|
+ // 计算解密后数据大小(预留额外空间)
|
|
|
+ const bufferSize = cipherLength + 16
|
|
|
+ const buffer = plus.ios.newObject('NSMutableData', 'dataWithLength:', bufferSize)
|
|
|
|
|
|
// 执行解密
|
|
|
- let decryptedLength = 0
|
|
|
- const status = CCCrypt(
|
|
|
- 1, // kCCDecrypt
|
|
|
- 0, // kCCAlgorithmAES
|
|
|
- 0x0001, // kCCOptionPKCS7Padding
|
|
|
+ let decryptedLength = plus.ios.newObject('NSUInteger')
|
|
|
+ const status = plus.ios.invoke('CCCrypt', ':',
|
|
|
+ 1, // kCCDecrypt = 1
|
|
|
+ 0, // kCCAlgorithmAES = 0
|
|
|
+ 0x0001, // kCCOptionPKCS7Padding = 0x0001
|
|
|
keyBytes,
|
|
|
keyData.length,
|
|
|
ivBytes,
|
|
|
cipherBytes,
|
|
|
cipherLength,
|
|
|
- buffer,
|
|
|
+ buffer.bytes,
|
|
|
bufferSize,
|
|
|
- decryptedLength
|
|
|
+ plus.ios.addrOf(decryptedLength)
|
|
|
)
|
|
|
|
|
|
- if (status !== 0) { // kCCSuccess
|
|
|
+ if (status !== 0) { // kCCSuccess = 0
|
|
|
console.error('AES 解密失败,状态码:', status)
|
|
|
return cipherText
|
|
|
}
|
|
|
|
|
|
+ // 设置实际数据长度
|
|
|
+ buffer.setLength(decryptedLength)
|
|
|
+
|
|
|
// 转为字符串
|
|
|
- const decryptedData = NSData.dataWithBytesLength(buffer, decryptedLength)
|
|
|
- const decryptedStr = NSString.alloc().initWithDataEncoding(decryptedData, NSUTF8StringEncoding)
|
|
|
+ const decryptedStr = plus.ios.invoke('NSString', 'alloc')
|
|
|
+ const resultStr = plus.ios.invoke(decryptedStr, 'initWithData:encoding:', buffer, 4) // NSUTF8StringEncoding = 4
|
|
|
|
|
|
- return decryptedStr.toString()
|
|
|
+ return String(resultStr)
|
|
|
} 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)
|
|
|
+// 或者更简洁的 iOS 实现版本(使用 UTS 的 plus.ios API)
|
|
|
function encryptAESiOS_simple(plainText: string, keyStr: string, ivStr: string): string {
|
|
|
try {
|
|
|
- // 使用 CommonCrypto
|
|
|
- const plainData = plainText.toNSData()
|
|
|
- const keyData = keyStr.toNSData()
|
|
|
- const ivData = ivStr.toNSData()
|
|
|
+ // 创建 CCCryptor
|
|
|
+ const cryptorRef = plus.ios.newObject('CCCryptorRef')
|
|
|
|
|
|
- // 创建加密上下文
|
|
|
- const cryptor = NSMutableData.dataWithLength(plainData.length + 16)
|
|
|
- let dataOutMoved = 0
|
|
|
+ // 创建密钥和 IV 数据
|
|
|
+ const keyData = plus.ios.invoke('NSData', 'dataWithBytes:length:',
|
|
|
+ plus.ios.newObject('NSString', 'stringWithString:', keyStr).UTF8String,
|
|
|
+ keyStr.length)
|
|
|
+
|
|
|
+ const ivData = plus.ios.invoke('NSData', 'dataWithBytes:length:',
|
|
|
+ plus.ios.newObject('NSString', 'stringWithString:', ivStr).UTF8String,
|
|
|
+ ivStr.length)
|
|
|
+
|
|
|
+ const plainData = plus.ios.invoke('NSData', 'dataWithBytes:length:',
|
|
|
+ plus.ios.newObject('NSString', 'stringWithString:', plainText).UTF8String,
|
|
|
+ plainText.length)
|
|
|
|
|
|
- const status = CCCrypt(
|
|
|
+ // 创建输出缓冲区
|
|
|
+ const bufferSize = plainData.length + 16
|
|
|
+ const buffer = plus.ios.invoke('NSMutableData', 'dataWithLength:', bufferSize)
|
|
|
+
|
|
|
+ // 执行加密
|
|
|
+ let dataOutMoved = 0
|
|
|
+ const status = plus.ios.invoke('CCCrypt',
|
|
|
0, // kCCEncrypt
|
|
|
0, // kCCAlgorithmAES128
|
|
|
1, // kCCOptionPKCS7Padding
|
|
|
@@ -281,14 +300,15 @@ function encryptAESiOS_simple(plainText: string, keyStr: string, ivStr: string):
|
|
|
ivData.bytes,
|
|
|
plainData.bytes,
|
|
|
plainData.length,
|
|
|
- cryptor.mutableBytes,
|
|
|
- cryptor.length,
|
|
|
+ buffer.bytes,
|
|
|
+ buffer.length,
|
|
|
dataOutMoved
|
|
|
)
|
|
|
|
|
|
if (status === 0) { // kCCSuccess
|
|
|
- cryptor.length = dataOutMoved
|
|
|
- return cryptor.base64EncodedStringWithOptions(0)
|
|
|
+ buffer.setLength(dataOutMoved)
|
|
|
+ const base64Str = buffer.base64EncodedStringWithOptions(0)
|
|
|
+ return String(base64Str)
|
|
|
} else {
|
|
|
console.error('加密失败,错误码:', status)
|
|
|
return plainText
|
|
|
@@ -302,15 +322,29 @@ function encryptAESiOS_simple(plainText: string, keyStr: string, ivStr: string):
|
|
|
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 cipherData = plus.ios.invoke('NSData', 'alloc')
|
|
|
+ const initData = plus.ios.invoke(cipherData, 'initWithBase64EncodedString:options:', cipherText, 0)
|
|
|
|
|
|
- // 创建解密上下文
|
|
|
- const cryptor = NSMutableData.dataWithLength(cipherData.length + 16)
|
|
|
- let dataOutMoved = 0
|
|
|
+ if (!initData) {
|
|
|
+ console.error('解密失败:Base64 解码失败')
|
|
|
+ return cipherText
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建密钥和 IV 数据
|
|
|
+ const keyData = plus.ios.invoke('NSData', 'dataWithBytes:length:',
|
|
|
+ plus.ios.newObject('NSString', 'stringWithString:', keyStr).UTF8String,
|
|
|
+ keyStr.length)
|
|
|
+
|
|
|
+ const ivData = plus.ios.invoke('NSData', 'dataWithBytes:length:',
|
|
|
+ plus.ios.newObject('NSString', 'stringWithString:', ivStr).UTF8String,
|
|
|
+ ivStr.length)
|
|
|
|
|
|
- const status = CCCrypt(
|
|
|
+ // 创建输出缓冲区
|
|
|
+ const buffer = plus.ios.invoke('NSMutableData', 'dataWithLength:', cipherData.length)
|
|
|
+
|
|
|
+ // 执行解密
|
|
|
+ let dataOutMoved = 0
|
|
|
+ const status = plus.ios.invoke('CCCrypt',
|
|
|
1, // kCCDecrypt
|
|
|
0, // kCCAlgorithmAES128
|
|
|
1, // kCCOptionPKCS7Padding
|
|
|
@@ -319,14 +353,16 @@ function decryptAESiOS_simple(cipherText: string, keyStr: string, ivStr: string)
|
|
|
ivData.bytes,
|
|
|
cipherData.bytes,
|
|
|
cipherData.length,
|
|
|
- cryptor.mutableBytes,
|
|
|
- cryptor.length,
|
|
|
+ buffer.bytes,
|
|
|
+ buffer.length,
|
|
|
dataOutMoved
|
|
|
)
|
|
|
|
|
|
if (status === 0) { // kCCSuccess
|
|
|
- cryptor.length = dataOutMoved
|
|
|
- return NSString.alloc().initWithDataEncoding(cryptor, NSUTF8StringEncoding)
|
|
|
+ buffer.setLength(dataOutMoved)
|
|
|
+ const resultStr = plus.ios.invoke('NSString', 'alloc')
|
|
|
+ const finalStr = plus.ios.invoke(resultStr, 'initWithData:encoding:', buffer, 4) // NSUTF8StringEncoding = 4
|
|
|
+ return String(finalStr)
|
|
|
} else {
|
|
|
console.error('解密失败,错误码:', status)
|
|
|
return cipherText
|
|
|
@@ -336,18 +372,6 @@ function decryptAESiOS_simple(cipherText: string, keyStr: string, ivStr: string)
|
|
|
return cipherText
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-// 扩展 String 类型以添加 toNSData 方法
|
|
|
-declare global {
|
|
|
- interface String {
|
|
|
- toNSData(): any
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 为 String 添加 toNSData 方法
|
|
|
-String.prototype.toNSData = function(): any {
|
|
|
- return NSString.stringWithString(this).dataUsingEncoding(NSUTF8StringEncoding)
|
|
|
-}
|
|
|
// #endif
|
|
|
|
|
|
|