I've been trying to encrypt and decrypt a string in swift using a Diffie Hellman key exchange and an elliptic curve encryption. But after the key exchange I can't restore a private key from a CFData shared1/shared2 variable for decryption. All i get is nil value.
let attributes: [String: Any] = [kSecAttrKeySizeInBits as String: 256,
kSecAttrKeyType as String: kSecAttrKeyTypeEC,
kSecPrivateKeyAttrs as String: [kSecAttrIsPermanent as String: false]]
var error: Unmanaged<CFError>?
if #available(iOS 10.0, *) {
guard let privateKey1 = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {return}
let publicKey1 = SecKeyCopyPublicKey(privateKey1)
guard let privateKey2 = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {return}
let publicKey2 = SecKeyCopyPublicKey(privateKey2)
let dict: [String: Any] = [:]
guard let shared1 = SecKeyCopyKeyExchangeResult(privateKey1, SecKeyAlgorithm.ecdhKeyExchangeStandardX963SHA256, publicKey2!, dict as CFDictionary, &error) else {return}
guard let shared2 = SecKeyCopyKeyExchangeResult(privateKey2, SecKeyAlgorithm.ecdhKeyExchangeStandardX963SHA256, publicKey1!, dict as CFDictionary, &error) else {return}
print(shared1==shared2)
let options: [String: Any] = [kSecAttrKeyType as String: kSecAttrKeyTypeEC,
kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
kSecAttrKeySizeInBits as String : 256]
guard let key = SecKeyCreateWithData(shared1 as CFData,
options as CFDictionary,
&error) else {return}
print(key)
let str = "Hello"
let byteStr: [UInt8] = Array(str.utf8)
let cfData = CFDataCreate(nil, byteStr, byteStr.count)
guard let encrypted = SecKeyCreateEncryptedData(publicKey1!,
SecKeyAlgorithm.eciesEncryptionStandardX963SHA256AESGCM,
cfData!,
&error) else {return}
guard let decrypted = SecKeyCreateDecryptedData(key,
SecKeyAlgorithm.eciesEncryptionStandardX963SHA256AESGCM,
encrypted,
&error) else {return}
print(decrypted)
} else {
print("unsupported")
}
SecKeyFromData Restores a key from an external representation of that key. The value you're passing to it is not an external representation of a key, it's a shared secret(CFData) just some bytes. You have to derive a key using some KDF on the shared secret then you can use it for encryption and decryption.
And the keys you're using for encryption and decryption are wrong, you have to choose if you want to do asymmetric or symmetric encryption.
SecKeyFromData:
https://developer.apple.com/documentation/security/1643701-seckeycreatewithdata
Related
I need to decrypt data with a RSA public key on macOS, by googling I know we can use method SecKeyCreateDecryptedData of Security.framework to achieve that, but it leads to two problems:
SecKeyCreateDecryptedData accepts a private key to execute decryption, but in my situation, the data is encrypted with private key in the server-end, and needs to be decrypted with public key in the client-end.
I tried to create SecKey from a RSA public key string, but failed.
My code:
import Foundation
func getPublicKey(from data: Data) throws -> SecKey {
var error: Unmanaged<CFError>? = nil
let publicKeyMaybe = SecKeyCreateWithData(
data as NSData,
[
kSecAttrKeyType: kSecAttrKeyTypeRSA,
kSecAttrKeyClass: kSecAttrKeyClassPublic
] as NSDictionary,
&error)
guard let publicKey = publicKeyMaybe else {
throw error!.takeRetainedValue() as Error
}
return publicKey
}
func decrypt(key: SecKey, data cipherTextData: Data) -> Data? {
let algorithm: SecKeyAlgorithm = .eciesEncryptionCofactorVariableIVX963SHA256AESGCM
guard SecKeyIsAlgorithmSupported(key, .decrypt, algorithm) else {
print("Can't decrypt. Algorithm not supported.")
return nil
}
var error: Unmanaged<CFError>? = nil
let clearTextData = SecKeyCreateDecryptedData(key,
algorithm,
cipherTextData as CFData,
&error) as Data?
if let error = error {
print("Can't decrypt. %#", (error.takeRetainedValue() as Error).localizedDescription)
return nil
}
guard clearTextData != nil else {
print("Can't decrypt. No resulting cleartextData.")
return nil
}
print("Decrypted data.")
return clearTextData
}
func testDecrypt() {
let rawString = "0ed3a2c57f5dEJgqXT9760269b8cc5cd76f3afcf"
let decodedData = Data.init(base64Encoded: rawString, options: [])!
let pubKey = try! getPublicKey(from: kPubKey.data(using: .utf8)!) // Error: RSA public key creation from data failed
let decryptedData = decrypt(key: pubKey, data: decodedData)!
let decrypted = String.init(data: decryptedData, encoding: .utf8)!
print(">>>>>>> decrypted string: \(decrypted)")
}
testDecrypt()
With method of Kazunori Takaishi, I tested all the algorithm, none of them is supported:
func decrypt(key: SecKey, data cipherTextData: Data) -> Data? {
let algorithms: [SecKeyAlgorithm] = [
.rsaSignatureRaw,
.rsaSignatureDigestPKCS1v15Raw,
.rsaSignatureDigestPKCS1v15SHA1,
.rsaSignatureDigestPKCS1v15SHA224,
.rsaSignatureDigestPKCS1v15SHA256,
.rsaSignatureDigestPKCS1v15SHA384,
.rsaSignatureDigestPKCS1v15SHA512,
.rsaSignatureMessagePKCS1v15SHA1,
.rsaSignatureMessagePKCS1v15SHA224,
.rsaSignatureMessagePKCS1v15SHA256,
.rsaSignatureMessagePKCS1v15SHA384,
.rsaSignatureMessagePKCS1v15SHA512,
.rsaSignatureDigestPSSSHA1,
.rsaSignatureDigestPSSSHA224,
.rsaSignatureDigestPSSSHA256,
.rsaSignatureDigestPSSSHA384,
.rsaSignatureDigestPSSSHA512,
.rsaSignatureMessagePSSSHA1,
.rsaSignatureMessagePSSSHA224,
.rsaSignatureMessagePSSSHA256,
.rsaSignatureMessagePSSSHA384,
.rsaSignatureMessagePSSSHA512,
.ecdsaSignatureRFC4754,
.ecdsaSignatureDigestX962,
.ecdsaSignatureDigestX962SHA1,
.ecdsaSignatureDigestX962SHA224,
.ecdsaSignatureDigestX962SHA256,
.ecdsaSignatureDigestX962SHA384,
.ecdsaSignatureDigestX962SHA512,
.ecdsaSignatureMessageX962SHA1,
.ecdsaSignatureMessageX962SHA224,
.ecdsaSignatureMessageX962SHA256,
.ecdsaSignatureMessageX962SHA384,
.ecdsaSignatureMessageX962SHA512,
.rsaEncryptionRaw,
.rsaEncryptionPKCS1,
.rsaEncryptionOAEPSHA1,
.rsaEncryptionOAEPSHA224,
.rsaEncryptionOAEPSHA256,
.rsaEncryptionOAEPSHA384,
.rsaEncryptionOAEPSHA512,
.rsaEncryptionOAEPSHA1AESGCM,
.rsaEncryptionOAEPSHA224AESGCM,
.rsaEncryptionOAEPSHA256AESGCM,
.rsaEncryptionOAEPSHA384AESGCM,
.rsaEncryptionOAEPSHA512AESGCM,
.eciesEncryptionStandardX963SHA1AESGCM,
.eciesEncryptionStandardX963SHA224AESGCM,
.eciesEncryptionStandardX963SHA256AESGCM,
.eciesEncryptionStandardX963SHA384AESGCM,
.eciesEncryptionStandardX963SHA512AESGCM,
.eciesEncryptionCofactorX963SHA1AESGCM,
.eciesEncryptionCofactorX963SHA224AESGCM,
.eciesEncryptionCofactorX963SHA256AESGCM,
.eciesEncryptionCofactorX963SHA384AESGCM,
.eciesEncryptionCofactorX963SHA512AESGCM,
.eciesEncryptionStandardVariableIVX963SHA224AESGCM,
.eciesEncryptionStandardVariableIVX963SHA256AESGCM,
.eciesEncryptionStandardVariableIVX963SHA384AESGCM,
.eciesEncryptionStandardVariableIVX963SHA512AESGCM,
.eciesEncryptionCofactorVariableIVX963SHA224AESGCM,
.eciesEncryptionCofactorVariableIVX963SHA256AESGCM,
.eciesEncryptionCofactorVariableIVX963SHA384AESGCM,
.eciesEncryptionCofactorVariableIVX963SHA512AESGCM,
.ecdhKeyExchangeStandard,
.ecdhKeyExchangeStandardX963SHA1,
.ecdhKeyExchangeStandardX963SHA224,
.ecdhKeyExchangeStandardX963SHA256,
.ecdhKeyExchangeStandardX963SHA384,
.ecdhKeyExchangeStandardX963SHA512,
.ecdhKeyExchangeCofactor,
.ecdhKeyExchangeCofactorX963SHA1,
.ecdhKeyExchangeCofactorX963SHA224,
.ecdhKeyExchangeCofactorX963SHA256,
.ecdhKeyExchangeCofactorX963SHA384,
.ecdhKeyExchangeCofactorX963SHA512
]
for a in algorithms {
if SecKeyIsAlgorithmSupported(key, .decrypt, a) {
print(">>>>>>>>>>>>> supported algorithm: \(a)")
}
}
//==================
let algorithm: SecKeyAlgorithm = .rsaEncryptionPKCS1 // .rsaSignatureMessagePKCS1v15SHA256 // .rsaSignatureDigestPKCS1v15SHA1 // .rsaSignatureDigestPKCS1v15Raw // .rsaSignatureDigestPKCS1v15SHA256 //.rsaEncryptionPKCS1
// guard SecKeyIsAlgorithmSupported(key, .decrypt, algorithm) else {
// print("Can't decrypt. Algorithm not supported.")
// return nil
// }
var error: Unmanaged<CFError>? = nil
let clearTextData = SecKeyCreateDecryptedData(key,
algorithm,
cipherTextData as CFData,
&error) as Data?
if let error = error {
print("Can't decrypt. \((error.takeRetainedValue() as Error).localizedDescription)")
return nil
}
guard clearTextData != nil else {
print("Can't decrypt. No resulting cleartextData.")
return nil
}
print("Decrypted data.")
return clearTextData
}
If your code only works on Mac OS, you may be able to create a Seckey by using the SecKeyCreateFromData method instead of the SecKeyCreateWithData method.
Here is Sample Code:
func getPublicKey(from data: Data?) throws -> SecKey {
var error: Unmanaged<CFError>? = nil
guard let data = data else { throw error!.takeRetainedValue() as Error }
let publicKeyMaybe = SecKeyCreateFromData([:] as CFDictionary, data as NSData, &error)
guard let publicKey = publicKeyMaybe else {
throw error!.takeRetainedValue() as Error
}
return publicKey
}
And You should convert RSA public key string to data using ASCII encoding.
let pubKey = try! getPublicKey(from: kPubKey.data(using: .ascii))
I'm trying to save a nested dictionary in userDefaults.
The app crashes when I try to save it the usual way, i.e.
defaults.set(totalBuy, forKey: "test")
and I get this error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object
And when I try convert it to NSData and then try retrieve it, it always comes back as nil.
Here is the code:
var buyData = [Int : String]()
var buyingTotal = [String : [Int: String]]()
var totalBuy = [Int : [String : [Int: String]]]()
let buyerDict = defaults.dictionary(forKey: "buyerDict")
let test = defaults.dictionary(forKey: "test")
func userDefaultSave(){
buyData[0] = value
buyData[1] = value
buyData[2] = value
buyData[3] = value
buyingTotal["skuu"] = buyData
totalBuy[0] = buyingTotal
let data: Data = NSKeyedArchiver.archivedData(withRootObject: totalBuy) /// converts to NS Data
defaults.set(data, forKey: "buyerDict")
defaults.set(totalBuy, forKey: "test")
if let dic = defaults.dictionary(forKey: "test") as? [Int : [String : [Int: String]]] {
print(dic)
}
let retrieved = defaults.object(forKey: "buyerDict") as! Data
let dictionary: Dictionary? = NSKeyedUnarchiver.unarchiveObject(with: retrieved) as? [String : Any]
print("dictionary--->", dictionary as Any)
}
Can anyone help me?
There are 2 ways you can get this working.
1. You can use JSONEncoder() and JSONDecoder() to get the data to and from the Dictionary object, i.e.
To get the data from totalBuy,
if let data = try? JSONEncoder().encode(totalBuy) {
defaults.set(data, forKey: "buyerDict")
}
To get the Dictionary from data,
if let data = defaults.data(forKey: "buyerDict"), let dict = try? JSONDecoder().decode([Int:[String:[Int:String]]].self, from: data) {
print(dict)
}
2. In case you still want to use NSKeyedArchiver and NSKeyedArchiver, here you go
To get the data from totalBuy,
let data = try? NSKeyedArchiver.archivedData(withRootObject: totalBuy)
defaults.set(data, forKey: "buyerDict")
To get the Dictionary from data,
if let data = defaults.data(forKey: "buyerDict") {
let dict = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)
print(dict)
}
Use data(forKey:) instead of object(forKey:) when retrieving the data from UserDefaults.
your dictionary need to change key Int to String Or convert dictionary to Data and retrieve it.
try this method to set and get your value from userdefault
let USERDEFAULT = UserDefaults.standard
class func setUserValueArchiver(value:Any, key :String) -> Void{
guard !(value is NSNull) else {
return
}
do{
let archive = try NSKeyedArchiver.archivedData(withRootObject: value, requiringSecureCoding: true)
USERDEFAULT.set(archive, forKey: key)
USERDEFAULT.synchronize()
}catch let error{
Log("Error Save in UserDefault \(error.localizedDescription)")
}
}
class func getUserUnArchiveData(key : String) -> Any?{
if let userdata = USERDEFAULT.object(forKey: key) as? Data{
do{
let unarchived = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(userdata)
return unarchived
}catch let error{
Log("Error At Get UserDATA :\(error.localizedDescription)")
}
}
return nil
}
I'm trying to sign and verify a challenge with elliptic curve algorithms using Apple tools.
Using the SecKeyCreateWithData I can use/import already generated public/private keys, this works great. Then I call the sign() function which takes SecKeyAlgorithm parameter. In my case is ecdsaSignatureDigestX962 because I use secp256r1 curve (NIST P-256). So the signature doesn't failed but then the verify always crash with :
Can't verify/wrong signature Unmanaged<CFErrorRef>(_value: Error Domain=NSOSStatusErrorDomain Code=-67808 "EC signature verification failed (ccerr -7)" UserInfo={NSDescription=EC signature verification failed (ccerr -7)})
Here is my complete code if someone has an idea :
import UIKit
class SecureEnclave: UIViewController {
var publicKey: SecKey!
var privateKey: SecKey!
var signature: Data!
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 10.0, *) {
var error: Unmanaged<CFError>?
//Step 1: Private Key
let privKeyUInt8: [UInt8] = [0x04,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0xde,0x0a,0x37,0x02,0xfc,0xc6,0x04,0x5b,0x03,0xd7,0x12,0x03,0x26,0x6a,0x4b,0x3d,0x05,0x55,0x5d,0x90,0xe1,0xa4,0xcf,0xd1,0x78,0xf7,0x95,0xda,0xa3,0x9c,0x**,0x2c,0x37,0x4f,0x**,0xfa,0x28,0x2e,0x64,0x7a,0x22,0x7f,0x47,0x9a,0x98,0x1a,0x2c,0x9b,0x2d,0x28,0x96,0xe0,0x**,0x07,0x33,0x06,0x10,0x5a,0x95,0x85,0x9c,0xc3,0xfd,0x43,0xf4,0x81,0x95,0xf4,0xe5,0x6d,0xb2,0x**,0x**,0x**,0x87,0x6d,0xc1,0x52,0x89,0xd3,0x05]
let CFPrivData = CFDataCreate(nil, privKeyUInt8, privKeyUInt8.count)
let optionsPrivKey: [String: Any] = [
kSecAttrKeyType as String : kSecAttrKeyTypeEC,
kSecAttrKeyClass as String : kSecAttrKeyClassPrivate,
]
guard let privKey = SecKeyCreateWithData(CFPrivData!, optionsPrivKey as CFDictionary, &error) else {
let error = error!.takeRetainedValue() as Error
return print(error)
}
self.privateKey = privKey
//Step 2: Public Key
let pubKeyUInt8: [UInt8] = [0x04,0x09,0x44,0x11,0xc6,0xbe,0x9f,0x31,0x88,0xa0,0x23,0xe7,0xf1,0x77,0x13,0xef,0xde,0x0a,0x37,0x02,0xfc,0xc6,0x04,0x5b,0x03,0xd7,0x12,0x03,0x26,0x6a,0x4b,0x3d,0x05,0x55,0x5d,0x90,0xe1,0xa4,0xcf,0xd1,0x78,0xf7,0x95,0xda,0xa3,0x9c,0x18,0x2c,0x37,0x4f,0x1b,0xfa,0x28,0x2e,0x64,0x7a,0x22,0x7f,0x47,0x9a,0x98,0x1a,0x2c,0x9b,0x2d]
let CFPubData = CFDataCreate(nil, pubKeyUInt8, pubKeyUInt8.count)
let optionsPubKey: [String: Any] = [kSecAttrKeyType as String: kSecAttrKeyTypeEC,
kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
kSecAttrKeySizeInBits as String: 256]
guard let pubKey = SecKeyCreateWithData(CFPubData!, optionsPubKey as CFDictionary, &error) else {
let error = error!.takeRetainedValue() as Error
return print(error)
}
self.publicKey = pubKey
//Step 3: Signing/Verifing
let challengeString = "Hello"
let challengeData = challengeString.data(using: .utf8)
self.sign(algorithm: .ecdsaSignatureDigestX962, data: challengeData!)
} else {
print("unsupported")
}
}
private func sign(algorithm: SecKeyAlgorithm, data: Data) {
guard SecKeyIsAlgorithmSupported(self.privateKey!, .sign, algorithm) else {
print("Algorith not supported - Can't sign")
return
}
// SecKeyCreateSignature call is blocking when the used key
// is protected by biometry authentication. If that's not the case,
// dispatching to a background thread isn't necessary.
DispatchQueue.global().async {
var error: Unmanaged<CFError>?
let signature = SecKeyCreateSignature(self.privateKey!, algorithm, data as CFData, &error) as Data?
DispatchQueue.main.async {
self.signature = signature
guard signature != nil else {
print((error!.takeRetainedValue() as Error).localizedDescription)
return
}
print("Signature : OK !")
//Step 4: Verifing
let algorithm: SecKeyAlgorithm = .ecdsaSignatureDigestX962
guard SecKeyIsAlgorithmSupported(self.publicKey, .verify, algorithm) else {
print("Algorith not supported - Can't verify")
return
}
var error: Unmanaged<CFError>?
guard SecKeyVerifySignature(self.publicKey, algorithm, data as CFData, self.signature as CFData, &error) else {
print("Can't verify/wrong signature \(error!)")
return
}
print("Signature check: OK")
}
}
}
}
Hi I want to encrypt Json Payload using public key that is .cer file. Please suggest how to do this?
let path = Bundle.main.path(forResource: "Keys123_1", ofType: "cer")
//get the data asociated to this file
let urlStt = URL(fileURLWithPath: path!)
if let base64String = try? Data(contentsOf: urlStt).base64EncodedString() {
print(base64String)
let data2 = Data.init(base64Encoded: base64String)
let keyDict:[NSObject:NSObject] = [
kSecAttrKeyType: kSecAttrKeyTypeRSA,
kSecAttrKeyClass: kSecAttrKeyClassPublic,
kSecAttrKeySizeInBits: NSNumber(value: 2048),
kSecReturnPersistentRef: true as NSObject
]
var error:Unmanaged<CFError>? = nil
guard let key = SecKeyCreateWithData(data2 as! CFData, keyDict as CFDictionary, &error) else {
print(error)
return
}
I am getting this error :
Optional(Swift.Unmanaged<__ObjC.CFError>(_value: Error Domain=NSOSStatusErrorDomain Code=-50 "RSA public key creation from data failed" UserInfo={NSDescription=RSA public key creation from data failed}))
Try this code and encrypt with public key and verify data by decrypt with private key on server side. I followed this link.
May be this work for you.
func getPublicKey() -> SecKey? {
let certificateData = try! Data(contentsOf: Bundle.main.url(forResource: "public", withExtension: "cer")!)
let certificate = SecCertificateCreateWithData(nil, certificateData as CFData)
var trust: SecTrust?
let policy = SecPolicyCreateBasicX509()
let status = SecTrustCreateWithCertificates(certificate!, policy, &trust)
if status == errSecSuccess {
let publicKey = SecTrustCopyPublicKey(trust!)!
return publicKey
}
return nil
}
I have project where I need to sign string(raw or base64 encoded) with private digital signature (that has password). I searched on internet and found that private digital certificate is x.509 format(RSA). In xcode I set UIFileSharingEnabled to Enabled and uploaded that rsa.p12 certificate using Itunes. Next I get the certificate from document directory in (data or string) format. My question is how can I encrypt any text using digital signature?
I tried to use this lib https://github.com/TakeScoop/SwiftyRSA/issues but this lib does not support x.509 certificate.
I just found the code which encodes string text and it works
func signRequestorId(requestorID: String) -> String? {
let name = "RSA256_4f1826090c554a439c419043270d40f7d.p12"
guard let certificateData = CustomFileManager.getFile(by: name) else {
return nil
}
var status: OSStatus
let certificateKey = "123456"
let options = [kSecImportExportPassphrase as String : certificateKey]
var optItems: CFArray?
status = SecPKCS12Import(certificateData as CFData, options as CFDictionary, &optItems)
if status != errSecSuccess {
print("Cannot sign the device id info: failed importing keystore.")
return nil
}
guard let items = optItems else {
return nil
}
// Cast CFArrayRef to Swift Array
let itemsArray = items as [AnyObject]
// Cast CFDictionaryRef as Swift Dictionary
guard let myIdentityAndTrust = itemsArray.first as? [String : AnyObject] else {
return nil
}
// Get our SecIdentityRef from the PKCS #12 blob
let outIdentity = myIdentityAndTrust[kSecImportItemIdentity as String] as! SecIdentity
var myReturnedCertificate: SecCertificate?
status = SecIdentityCopyCertificate(outIdentity, &myReturnedCertificate)
if status != errSecSuccess {
print("Failed to retrieve the certificate associated with the requested identity.")
return nil
}
// Get the private key associated with our identity
var optPrivateKey: SecKey?
status = SecIdentityCopyPrivateKey(outIdentity, &optPrivateKey)
if status != errSecSuccess {
print("Failed to extract the private key from the keystore.")
return nil
}
// Unwrap privateKey from optional SecKeyRef
guard let privateKey = optPrivateKey else {
return nil
}
// Retrieve the digital signature and sign the requestor
// Get the maximum size of the digital signature
var signedBytesSize: size_t = SecKeyGetBlockSize(privateKey)
var signedBytes: UnsafeMutablePointer<UInt8>
// alloc a buffer to hold the signature
signedBytes = UnsafeMutablePointer<UInt8>.allocate(capacity: signedBytesSize)
memset(signedBytes, 0x0, signedBytesSize)
// We're calling alloc here, so we need to destroy and deinit
defer {
signedBytes.deinitialize()
signedBytes.deallocate(capacity: signedBytesSize)
}
// Sign data
let requestorData = requestorID.data(using: String.Encoding.utf8)!
// Generate a digital signature for our requestor from our cert
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: requestorData.count)
let stream = OutputStream(toBuffer: buffer, capacity: requestorData.count)
stream.open()
requestorData.withUnsafeBytes({ (p: UnsafePointer<UInt8>) -> Void in
stream.write(p, maxLength: requestorData.count)
})
stream.close()
let weidformat = UnsafePointer<UInt8>(buffer)
status = SecKeyRawSign(privateKey, .PKCS1, weidformat,
requestorData.count, signedBytes, &signedBytesSize)
if status != errSecSuccess {
print("Cannot sign the device id info: failed obtaining the signed bytes.")
return nil
}
let encryptedBytes = NSData(bytes: signedBytes, length: signedBytesSize)
let signedRequestorId = encryptedBytes.base64EncodedString(options: [])
print(signedRequestorId)
return signedRequestorId
}
U also need function get document by name
static func getFile(by name: String)-> Data?{
let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let destinationUrl = documentsUrl!.appendingPathComponent("\(name)")
let isFileFound = FileManager.default.fileExists(atPath: destinationUrl.path)
if isFileFound {
let documentContent = FileManager.default.contents(atPath: destinationUrl.path)
return documentContent
}
return nil
}
enter code here