In Swift, I created a SecKeyRef
object by calling SecTrustCopyPublicKey
on some raw X509 certificate data. This is what this SecKeyRef
object looks like.
Optional(<SecKeyRef algorithm id: 1,
key type: RSAPublicKey,
version: 3, block size: 2048 bits,
exponent: {hex: 10001, decimal: 65537},
modulus: <omitted a bunch of hex data>,
addr: 0xsomeaddresshere>)
Basically, this SecKeyRef
object holds a whole bunch of information about the public key, but there seems to be no way to actually convert this SecKeyRef
into a string, NSData
, or anything else (this is my goal, is just to get a base64 public key).
However, I have a function that I can give a modulus
and an exponent
, and it will just calculate what the public key is. I've tested it by passing in the data that's logged from the above SecKeyRef
.
But somehow I can't access those properties from the SecKeyRef
object (I can only see the whole object in the console; for example, I cannot do SecKeyRef.modulus
or anything of the sort, it seems).
My question: how can I access SecKeyRef.modulus
, or alternatively, convert this SecKeyRef
into NSData
or something similar? Thanks
Edit
(for more information)
I am creating my SecKeyRef
dynamically, through this function I have:
func bytesToPublicKey(certData: NSData) -> SecKeyRef? {
guard let certRef = SecCertificateCreateWithData(nil, certData) else { return nil }
var secTrust: SecTrustRef?
let secTrustStatus = SecTrustCreateWithCertificates(certRef, nil, &secTrust)
if secTrustStatus != errSecSuccess { return nil }
var resultType: SecTrustResultType = UInt32(0) // result will be ignored.
let evaluateStatus = SecTrustEvaluate(secTrust!, &resultType)
if evaluateStatus != errSecSuccess { return nil }
let publicKeyRef = SecTrustCopyPublicKey(secTrust!)
return publicKeyRef
}
What that does is takes the raw byte stream from a certificate (which can be broadcasted from, say, a piece of hardware using PKI), and then turns that into a SecKeyRef
.
Edit 2
(comments on existing answers as of 7 January 2015)
This does not work:
let mirror = Mirror(reflecting: mySecKeyObject)
for case let (label?, value) in mirror.children {
print (label, value)
}
This results in this output in the console:
Some <Raw SecKeyRef object>
Not sure what the string "Some" means.
Additionally, mirror.descendant("exponent")
(or "modulus") results in nil
, even though when printing the raw object in the console, I can clearly see that those properties exist, and that they are in fact populated.
Also, if at all possible, I would like to avoid having to save to the keychain, reading as NSData
, and then deleting from the keychain. As stated in the bounty description, if this is the only way possible, please cite an authoritative reference. Thank you for all answers provided so far.
Obj-C
but it is not difficult to translate. – Healllet mirrorKey = Mirror(reflecting: secKey); let exponent = mirrorKey.descendant("exponent"); let modulus = mirrorKey.descendant("modulus");
– HimalayasNSData
back. You can delete it after that. This way is also what I did in my production app. – SidewardSecKeyRef
is taking an array of bytes (in NSData form) as its parameter. If you want the public key in base64 you can get that from NSData. – Binaural