Re: Getting key data out of the keychain
Re: Getting key data out of the keychain
- Subject: Re: Getting key data out of the keychain
- From: Andreas Mayer <email@hidden>
- Date: Fri, 01 Jan 2016 14:09:20 +0100
Hello Marco,
> Am 31.12.2015 um 19:23 schrieb Marco S Hyman <email@hidden>:
>
> After much play, head scratching, and code that managed to add a bogus entry to the keychain that couldn’t be deleted (time machine to the rescue) I came up with one way to add an entry to the keychain and retrieve the entry: use the Generic Password class. In swift the code to fetch the password looked like this -- password returned as NSData.
thanks, but that's not what I was looking for.
Actually, I am able to save and retrieve the key just fine. It's just that I only get a SecKeyRef, not the binary data.
The trick to put a valid key into the keychain is to use SecKeyGenerateSymmetric() and have it save the key in the keychain immediately. You will then be able to retrieve it normally using SecItemCopyMatching().
To have SecKeyGenerateSymmetric() put the key into the default keychain, add the attribute kSecAttrIsPermanent with a value of true.
Or you can add the kSecUseKeychain attribute and supply the keychain you want it to use.
For now, I decided to work around the key bytes extraction problem by using SecTransforms - which take a SecKeyRef - for encoding instead of CCCrypt().
The reason I went with CCCrypt() first is, that I had a problem with creating SHA1 hashes with SecTransform and running that parallel inside an NSOperation. My application actually locked up with dozens of those NSOperations waiting on some semaphore. So I had to use CommonCrypto for that.
I didn't run into any problems with the SecEncrypt/DecryptTransform.
Here is my code if anyone is interested:
static func encryptData(data: NSData, withKey key: SecKeyRef) throws -> NSData {
return try cryptData(data, withKey: key, transformCreate: SecEncryptTransformCreate)
}
static func decryptData(data: NSData, withKey key: SecKeyRef) throws -> NSData {
return try cryptData(data, withKey: key, transformCreate: SecDecryptTransformCreate)
}
static func cryptData(data: NSData, withKey key: SecKeyRef, transformCreate: (SecKey, UnsafeMutablePointer<Unmanaged<CFError>?>) -> SecTransform) throws -> NSData {
var result: NSData?
var transform: SecTransformRef?
var error: Unmanaged<CFErrorRef>?
transform = transformCreate(key, &error)
if error != nil { let retainedError: ErrorType = error!.takeRetainedValue(); throw retainedError }
SecTransformSetAttribute(transform!, kSecPaddingKey, kSecPaddingPKCS7Key, &error);
if error != nil { let retainedError: ErrorType = error!.takeRetainedValue(); throw retainedError }
SecTransformSetAttribute(transform!, kSecTransformInputAttributeName,
data, &error);
if error != nil { let retainedError: ErrorType = error!.takeRetainedValue(); throw retainedError }
result = SecTransformExecute(transform!, &error) as? NSData;
if error != nil { let retainedError: ErrorType = error!.takeRetainedValue(); throw retainedError }
return result!
}
But I *still* don't know how to get at the key bytes of a SecKeyRef. :P
Andreas
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden