|
//
// Data+Encryption.swift
// Function
//
// Created by mac on 2016/11/9.
// Copyright © 2016年 mac. All rights reserved.
//
import UIKit
// MARK: RSA encrypt
extension Data {
fileprivate func rsa_publickey_form_data(keyData: Data) -> SecKey? {
if let certificate = SecCertificateCreateWithData(kCFAllocatorDefault, keyData as CFData) {
let policy = SecPolicyCreateBasicX509()
var trust: SecTrust?
if SecTrustCreateWithCertificates(certificate, policy, &trust) == errSecSuccess {
var trustResultType: SecTrustResultType = SecTrustResultType.invalid
if SecTrustEvaluate(trust!, &trustResultType) == errSecSuccess {
return SecTrustCopyPublicKey(trust!)!
}
}
}
return nil
}
fileprivate func rsa_privatekey_from_data(keyData: Data, withPassword password: String) -> SecKey? {
var privateKey: SecKey? = nil
let options: [String: String] = [kSecImportExportPassphrase as String: password]
var items: CFArray?
if SecPKCS12Import(keyData as CFData, options as CFDictionary, &items) == errSecSuccess {
if CFArrayGetCount(items) > 0 {
let d = unsafeBitCast(CFArrayGetValueAtIndex(items, 0), to: CFDictionary.self)
let k = Unmanaged.passUnretained(kSecImportItemIdentity).toOpaque()
let v = CFDictionaryGetValue(d, k)
let secIdentity = unsafeBitCast(v, to: SecIdentity.self)
if SecIdentityCopyPrivateKey(secIdentity, &privateKey) == errSecSuccess {
return privateKey
}
}
}
return nil
}
fileprivate func RSA(operation: String, key: SecKey) -> Data? {
let key_size = SecKeyGetBlockSize(key)
var encrypt_bytes = [UInt8](repeating: 0, count: key_size)
var output_size = key_size
if operation == "encrypt" {
if SecKeyEncrypt(key, SecPadding.PKCS1,
self.bytes, self.count,
&encrypt_bytes, &output_size) == errSecSuccess {
return Data(bytes: encrypt_bytes, count: output_size)
}
} else {
let stauts = SecKeyDecrypt(key, SecPadding.PKCS1,
self.bytes, self.count,
&encrypt_bytes, &output_size)
if stauts == errSecSuccess {
return Data(bytes: UnsafePointer<UInt8>(encrypt_bytes), count: output_size)
}
}
return nil
}
func RSAEncryptToData(publicKeyPath: String) -> Data {
let publicKey = try? Data(contentsOf: URL(fileURLWithPath: publicKeyPath))
let publickeyData = rsa_publickey_form_data(keyData: publicKey!)
return RSA(operation: "encrypt", key: publickeyData!)!
}
func RSAEncryptToBase64Data(publicKeyPath: String) -> Data {
return RSAEncryptToData(publicKeyPath: publicKeyPath).base64EncodedData()
}
func RSAEncryptToBase64String(publicKeyPath: String) -> String {
return RSAEncryptToData(publicKeyPath: publicKeyPath).base64EncodedString()
}
mutating func RSADecryptFromBase64DataToData(privateKeyPath: String) -> Data {
self = Data.init(base64Encoded: self)!
return RSADecryptToData(privateKeyPath: privateKeyPath)
}
mutating func RSADecryptFromBase64DataToString(privateKeyPath: String) -> String {
self = Data.init(base64Encoded: self)!
return RSADecryptToString(privateKeyPath: privateKeyPath)
}
func RSADecryptToData(privateKeyPath: String) -> Data {
let privateKey = try? Data(contentsOf: URL(fileURLWithPath: privateKeyPath))
let privateKeyData = rsa_privatekey_from_data(keyData: privateKey!, withPassword: "5995267")
return RSA(operation: "decrypt", key: privateKeyData!)!
}
func RSADecryptToString(privateKeyPath: String) -> String {
return String(data: RSADecryptToData(privateKeyPath: privateKeyPath), encoding: String.Encoding.utf8)!
}
}
extension String {
func RSAEncryptToData(publicKeyPath: String) -> Data {
return self.myData.RSAEncryptToData(publicKeyPath: publicKeyPath)
}
func RSAEncryptToBase64Data(publicKeyPath: String) -> Data {
return self.myData.RSAEncryptToBase64Data(publicKeyPath: publicKeyPath)
}
func RSAEncryptToBase64String(publicKeyPath: String) -> String {
return self.myData.RSAEncryptToBase64String(publicKeyPath: publicKeyPath)
}
func RSADecryptFromBase64StringToData(privateKeyPath: String) -> Data {
return (Data(base64Encoded: self)?.RSADecryptToData(privateKeyPath: privateKeyPath))!
}
func RSADecryptFromBase64StringToString(privateKeyPath: String) -> String {
return (Data(base64Encoded: self)?.RSADecryptToString(privateKeyPath: privateKeyPath))!
}
func RSADecryptToData(privateKeyPath: String) -> Data {
return self.myData.RSADecryptToData(privateKeyPath: privateKeyPath)
}
func RSADecryptToString(privateKeyPath: String) -> String {
return self.myData.RSADecryptToString(privateKeyPath: privateKeyPath)
}
}
|