125 lines
4.6 KiB
Swift
Executable File
125 lines
4.6 KiB
Swift
Executable File
//
|
|
// BrizziSamHelper.swift
|
|
// Emoney Info
|
|
//
|
|
// Created by Wira Irawan on 27/07/24.
|
|
//
|
|
|
|
import Foundation
|
|
import CommonCrypto
|
|
|
|
class BrizziSamHelper {
|
|
public var encryptedKey: String?
|
|
public var authKey = "0000030080000000"
|
|
public var keyCard: String?
|
|
public var random = ""
|
|
|
|
static func encryptDeSeDe(_ str: String, _ str2: String, _ str3: String) -> Data? {
|
|
var key = str2
|
|
if key.count != 48 {
|
|
if key.count == 32 {
|
|
key += key.prefix(16)
|
|
} else if key.count == 16 {
|
|
key += key + key
|
|
} else {
|
|
key = "00000000000000000000000000000000"
|
|
}
|
|
}
|
|
let keyData = key.hex2byte()
|
|
let ivData = str3.hex2byte()
|
|
|
|
return crypt(input: str.hex2byte(), keyData: keyData, ivData: ivData, operation: CCOperation(kCCEncrypt))
|
|
}
|
|
|
|
static func decryptDeSeDe(_ datas: Data) -> Data? {
|
|
let keyData = ("C152153D5807784C721A433B5B59636D" + "C152153D5807784C").hex2byte()
|
|
let ivData = ("0000000000000000").hex2byte()
|
|
|
|
return crypt(input: datas, keyData: keyData, ivData: ivData, operation: CCOperation(kCCDecrypt))
|
|
}
|
|
|
|
static func mix(_ bArr: [UInt8], _ bArr2: [UInt8]) -> [UInt8] {
|
|
guard !bArr2.isEmpty else {
|
|
return bArr
|
|
}
|
|
|
|
var bArr3 = [UInt8](repeating: 0, count: bArr.count)
|
|
var i = 0
|
|
for y in 0..<bArr.count {
|
|
bArr3[y] = bArr[y] ^ bArr2[i]
|
|
i += 1
|
|
if i >= bArr2.count {
|
|
i = 0
|
|
}
|
|
}
|
|
return bArr3
|
|
}
|
|
|
|
static func decrypt(_ data: String, _ key: String) -> Data? {
|
|
let keyData = key.hex2byte()
|
|
|
|
return crypt(input: data.hex2byte(), keyData: keyData, ivData: nil, operation: CCOperation(kCCDecrypt))
|
|
}
|
|
|
|
static func encrypt(_ str: String, _ key: String) -> Data? {
|
|
let substring = String(key.prefix(16))
|
|
guard let decryptedData = decrypt(str, substring) else {
|
|
return ("").hex2byte()
|
|
}
|
|
|
|
let a9 = decryptedData.hexEncodedString()
|
|
let keyData = String(key.dropFirst(16).prefix(16)).hex2byte()
|
|
|
|
guard let encryptedData = crypt(input: a9.hex2byte(), keyData: keyData, ivData: nil, operation: CCOperation(kCCEncrypt)) else {
|
|
return ("").hex2byte()
|
|
}
|
|
|
|
guard let finalDecryptedData = decrypt(encryptedData.hexEncodedString(), substring) else {
|
|
return ("").hex2byte()
|
|
}
|
|
|
|
return finalDecryptedData
|
|
}
|
|
|
|
func generateSamRandom() -> String {
|
|
guard
|
|
let keyCard = self.keyCard,
|
|
let encryptedCard = BrizziSamHelper.encrypt(keyCard, self.random)?.hexEncodedString()
|
|
else {
|
|
return ""
|
|
}
|
|
let sam = BrizziSamHelper.mix(encryptedCard.hex2byte().bytes, ("0000000000000000").hex2byte().bytes).hexString().subString(from: 0, to: 16)
|
|
guard sam.count == 16 else {
|
|
return ""
|
|
}
|
|
let sams = sam[sam.index(sam.startIndex, offsetBy: 2)..<sam.index(sam.startIndex, offsetBy: 16)] + sam[sam.startIndex..<sam.index(sam.startIndex, offsetBy: 2)]
|
|
guard let encryptedResult = BrizziSamHelper.encrypt((BrizziSamHelper.mix(("1122334455667788").hex2byte().bytes, keyCard.hex2byte().bytes).hexString()), self.random)?.hexEncodedString() else {
|
|
return ""
|
|
}
|
|
let result = encryptedResult.subString(from: 0, to: 16)
|
|
|
|
guard let finalResult = BrizziSamHelper.encrypt((BrizziSamHelper.mix(String(sams).hex2byte().bytes, result.hex2byte().bytes)).hexString(), self.random)?.hexEncodedString() else {
|
|
return result
|
|
}
|
|
return result + finalResult
|
|
}
|
|
|
|
private static func crypt(input: Data, keyData: Data, ivData: Data?, operation: CCOperation) -> Data? {
|
|
var outLength = Int(0)
|
|
var outBytes = [UInt8](repeating: 0, count: input.count + kCCBlockSize3DES)
|
|
var status: CCCryptorStatus
|
|
|
|
if let ivData = ivData {
|
|
status = CCCrypt(operation, CCAlgorithm(kCCAlgorithm3DES), CCOptions(kCCOptionPKCS7Padding), keyData.bytes, kCCKeySize3DES, ivData.bytes, input.bytes, input.count, &outBytes, outBytes.count, &outLength)
|
|
} else {
|
|
status = CCCrypt(operation, CCAlgorithm(kCCAlgorithmDES), CCOptions(kCCOptionPKCS7Padding), keyData.bytes, kCCKeySizeDES, nil, input.bytes, input.count, &outBytes, outBytes.count, &outLength)
|
|
}
|
|
|
|
guard status == kCCSuccess else {
|
|
return nil
|
|
}
|
|
|
|
return Data(bytes: outBytes, count: outLength)
|
|
}
|
|
}
|