Remove CryptoKit and add pbkdf2 in swift
This commit is contained in:
parent
9ea2b5247e
commit
2a5c719c2e
@ -1,6 +1,5 @@
|
|||||||
import Flutter
|
import Flutter
|
||||||
import UIKit
|
import UIKit
|
||||||
import CryptoKit
|
|
||||||
import CommonCrypto
|
import CommonCrypto
|
||||||
|
|
||||||
extension FlutterStandardTypedData {
|
extension FlutterStandardTypedData {
|
||||||
@ -14,16 +13,6 @@ extension FlutterStandardTypedData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CryptoKit.Digest utils
|
|
||||||
@available(iOS 13.0, *)
|
|
||||||
extension Digest {
|
|
||||||
var bytes: [UInt8] { Array(makeIterator()) }
|
|
||||||
var data: Data { Data(bytes) }
|
|
||||||
|
|
||||||
var hexStr: String {
|
|
||||||
bytes.map { String(format: "%02X", $0) }.joined()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func crypt(operation: Int, algorithm: Int, options: Int, key: Data,
|
func crypt(operation: Int, algorithm: Int, options: Int, key: Data,
|
||||||
initializationVector: Data, dataIn: Data) -> Data? {
|
initializationVector: Data, dataIn: Data) -> Data? {
|
||||||
@ -49,6 +38,37 @@ func crypt(operation: Int, algorithm: Int, options: Int, key: Data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func pbkdf2(hash: CCPBKDFAlgorithm, password: String, salt: String, keyByteCount: Int, rounds: Int) -> Data? {
|
||||||
|
let passwordData = password.data(using: .utf8)!
|
||||||
|
let saltData = salt.data(using: .utf8)!
|
||||||
|
var derivedKeyData = Data(repeating: 0, count: keyByteCount)
|
||||||
|
|
||||||
|
var localDerivedKeyData = derivedKeyData
|
||||||
|
|
||||||
|
let derivationStatus = derivedKeyData.withUnsafeMutableBytes { derivedKeyBytes in
|
||||||
|
saltData.withUnsafeBytes { saltBytes in
|
||||||
|
|
||||||
|
CCKeyDerivationPBKDF(
|
||||||
|
CCPBKDFAlgorithm(kCCPBKDF2),
|
||||||
|
password, passwordData.count,
|
||||||
|
saltBytes, saltData.count,
|
||||||
|
hash,
|
||||||
|
UInt32(rounds),
|
||||||
|
derivedKeyBytes, localDerivedKeyData.count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (derivationStatus != kCCSuccess) {
|
||||||
|
print("Error: \(derivationStatus)")
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
return derivedKeyData
|
||||||
|
}
|
||||||
|
|
||||||
|
func pbkdf2sha256(password: String, salt: String, keyByteCount: Int, rounds: Int) -> Data? {
|
||||||
|
return pbkdf2(hash: CCPBKDFAlgorithm(kCCPRFHmacAlgSHA256), password: password, salt: salt, keyByteCount: keyByteCount, rounds: rounds)
|
||||||
|
}
|
||||||
|
|
||||||
func randomGenerateBytes(count: Int) -> Data? {
|
func randomGenerateBytes(count: Int) -> Data? {
|
||||||
let bytes = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: 1)
|
let bytes = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: 1)
|
||||||
defer { bytes.deallocate() }
|
defer { bytes.deallocate() }
|
||||||
@ -85,9 +105,32 @@ extension Data {
|
|||||||
options: kCCOptionPKCS7Padding, key: key, initializationVector: iv,
|
options: kCCOptionPKCS7Padding, key: key, initializationVector: iv,
|
||||||
dataIn: ciphertext)
|
dataIn: ciphertext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Algorithm {
|
||||||
|
case sha256
|
||||||
|
|
||||||
|
var digestLength: Int {
|
||||||
|
switch self {
|
||||||
|
case .sha256: return Int(CC_SHA256_DIGEST_LENGTH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func hash(for algorithm: Algorithm) -> Data {
|
||||||
|
let hashBytes = UnsafeMutablePointer<UInt8>.allocate(capacity: algorithm.digestLength)
|
||||||
|
defer { hashBytes.deallocate() }
|
||||||
|
switch algorithm {
|
||||||
|
case .sha256:
|
||||||
|
withUnsafeBytes { (buffer) -> Void in
|
||||||
|
CC_SHA256(buffer.baseAddress!, CC_LONG(buffer.count), hashBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Data(bytes: hashBytes, count: algorithm.digestLength)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(iOS 13.0, *)
|
|
||||||
public class SwiftNativeCryptoPlugin: NSObject, FlutterPlugin {
|
public class SwiftNativeCryptoPlugin: NSObject, FlutterPlugin {
|
||||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||||
let channel = FlutterMethodChannel(name: "native.crypto.helper", binaryMessenger: registrar.messenger())
|
let channel = FlutterMethodChannel(name: "native.crypto.helper", binaryMessenger: registrar.messenger())
|
||||||
@ -97,13 +140,37 @@ public class SwiftNativeCryptoPlugin: NSObject, FlutterPlugin {
|
|||||||
|
|
||||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||||
switch call.method {
|
switch call.method {
|
||||||
|
case "pbkdf2":
|
||||||
|
let args = call.arguments as! NSDictionary
|
||||||
|
let password = args["password"] as! String
|
||||||
|
let salt = args["salt"] as! String
|
||||||
|
let keyLength = args["keyLength"] as! NSNumber
|
||||||
|
let iteration = args["iteration"] as! NSNumber
|
||||||
|
|
||||||
|
let keyBytes = pbkdf2sha256(password: password, salt: salt, keyByteCount: keyLength.intValue, rounds: iteration.intValue)
|
||||||
|
|
||||||
|
if keyBytes != nil {
|
||||||
|
result(FlutterStandardTypedData.init(bytes: keyBytes!))
|
||||||
|
} else {
|
||||||
|
result(FlutterError(code: "PBKDF2ERROR",
|
||||||
|
message: "PBKDF2 KEY IS NIL.",
|
||||||
|
details: nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
case "symKeygen":
|
case "symKeygen":
|
||||||
let args = call.arguments as! NSDictionary
|
let args = call.arguments as! NSDictionary
|
||||||
let keySize = args["size"] as! NSNumber
|
let keySize = args["size"] as! NSNumber
|
||||||
|
|
||||||
let keyBytes = symKeygen(keySize: keySize)!
|
let keyBytes = symKeygen(keySize: keySize)
|
||||||
|
|
||||||
result(FlutterStandardTypedData.init(bytes: keyBytes))
|
if keyBytes != nil {
|
||||||
|
result(FlutterStandardTypedData.init(bytes: keyBytes!))
|
||||||
|
} else {
|
||||||
|
result(FlutterError(code: "SYMKEYGENERROR",
|
||||||
|
message: "GENERATED KEY IS NIL.",
|
||||||
|
details: nil))
|
||||||
|
}
|
||||||
|
|
||||||
case "symEncrypt":
|
case "symEncrypt":
|
||||||
let args = call.arguments as! NSDictionary
|
let args = call.arguments as! NSDictionary
|
||||||
@ -124,9 +191,15 @@ public class SwiftNativeCryptoPlugin: NSObject, FlutterPlugin {
|
|||||||
|
|
||||||
let aesKey = (args["aesKey"] as! FlutterStandardTypedData).data
|
let aesKey = (args["aesKey"] as! FlutterStandardTypedData).data
|
||||||
|
|
||||||
let decryptedPayload = symDecrypt(payload: encryptedPayload, aesKey: aesKey)!
|
let decryptedPayload = symDecrypt(payload: encryptedPayload, aesKey: aesKey)
|
||||||
|
|
||||||
result(decryptedPayload)
|
if decryptedPayload != nil {
|
||||||
|
result(FlutterStandardTypedData.init(bytes: decryptedPayload!))
|
||||||
|
} else {
|
||||||
|
result(FlutterError(code: "DECRYPTIONERROR",
|
||||||
|
message: "DECRYPTED PAYLOAD IS NIL. MAYBE VERIFICATION MAC IS UNVALID.",
|
||||||
|
details: nil))
|
||||||
|
}
|
||||||
|
|
||||||
default: result(FlutterMethodNotImplemented)
|
default: result(FlutterMethodNotImplemented)
|
||||||
|
|
||||||
@ -134,8 +207,8 @@ public class SwiftNativeCryptoPlugin: NSObject, FlutterPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func digest(input : Data) -> Data {
|
func digest(input : Data) -> Data {
|
||||||
let hashed = SHA256.hash(data: input)
|
let hashed = input.hash(for: .sha256)
|
||||||
return hashed.data
|
return hashed
|
||||||
}
|
}
|
||||||
|
|
||||||
func symKeygen(keySize : NSNumber) -> Data? {
|
func symKeygen(keySize : NSNumber) -> Data? {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user