从 osx 钥匙串中检索钥匙
Retrieve key from osx keychain
我正在尝试从钥匙串中检索我的应用程序的密钥,以便它可以用于对服务器进行身份验证。我已成功将它存储在那里,但无法取回它。
func getClientKey(){
let keyValptr:UnsafeMutablePointer<UnsafeMutableRawPointer?>?
let lenPtr:UnsafeMutablePointer<UInt32>? = UInt32(13) //how do i do this?
_ = SecKeychainFindGenericPassword(nil,
UInt32(serviceName.characters.count), serviceName,
UInt32(accountName.characters.count), accountName,
lenPtr, keyValptr, nil)
print(keyValptr)
}
我已经评论了我遇到问题的行。我如何获得传递给函数的正确指针?它想要一个 UnsafeMutablePointer<UInt32>?
(我会在其中选择实际值)
一般来说,当你想传递UnsafeMutablePoiner<T>?
(或UnsafeMutablePoiner<T>
)时,声明一个T
类型的变量(不是指向T
的指针)然后传递它作为输入参数(前缀 &
)。
所以,具体到你的问题,你的传递方式keyValPtr
也是错误的。
对于参数passwordLength: UnsafeMutablePointer<UInt32>?
,需要声明一个UInt32
类型的变量。
而对于passwordData: UnsafeMutablePointer<UnsafeMutableRawPointer?>?
,你需要声明一个UnsafeMutableRawPointer?
.
类型的变量
而且,不幸的是,在很多情况下这可能不是一个关键问题,当将 Swift String
直接传递给 UnsafePointer<Int8>?
时,您需要根据 UTF-8 表示来计算长度.
你可能需要这样写:
func getClientKey() {
var keyVal: UnsafeMutableRawPointer? = nil
var len: UInt32 = 13 //<- this value is ignored though...
let status = SecKeychainFindGenericPassword(
nil,
UInt32(serviceName.utf8.count), serviceName, //### Use `utf8.count`
UInt32(accountName.utf8.count), accountName, //### Use `utf8.count`
&len, //### to pass `UnsafeMutablePointer<UInt32>?`, declare a variable of `UInt32`.
&keyVal, //### to pass `UnsafeMutablePointer<UnsafeMutableRawPointer?>?`, declare a variable of `UnsafeMutableRawPointer?`.
nil
)
if status == noErr {
let keyData = Data(bytes: keyVal!, count: Int(len))
//### As noted in the API reference of `SecKeychainFindGenericPassword`,
// "You should use the SecKeychainItemFreeContent function to free the memory pointed to by this parameter."
SecKeychainItemFreeContent(nil, keyVal)
print(keyData as NSData)
print(String(data: keyData, encoding: .utf8) ?? "?")
} else {
//You should not silently ignore erros...
print("Error: \(status)")
}
}
我正在尝试从钥匙串中检索我的应用程序的密钥,以便它可以用于对服务器进行身份验证。我已成功将它存储在那里,但无法取回它。
func getClientKey(){
let keyValptr:UnsafeMutablePointer<UnsafeMutableRawPointer?>?
let lenPtr:UnsafeMutablePointer<UInt32>? = UInt32(13) //how do i do this?
_ = SecKeychainFindGenericPassword(nil,
UInt32(serviceName.characters.count), serviceName,
UInt32(accountName.characters.count), accountName,
lenPtr, keyValptr, nil)
print(keyValptr)
}
我已经评论了我遇到问题的行。我如何获得传递给函数的正确指针?它想要一个 UnsafeMutablePointer<UInt32>?
(我会在其中选择实际值)
一般来说,当你想传递UnsafeMutablePoiner<T>?
(或UnsafeMutablePoiner<T>
)时,声明一个T
类型的变量(不是指向T
的指针)然后传递它作为输入参数(前缀 &
)。
所以,具体到你的问题,你的传递方式keyValPtr
也是错误的。
对于参数passwordLength: UnsafeMutablePointer<UInt32>?
,需要声明一个UInt32
类型的变量。
而对于passwordData: UnsafeMutablePointer<UnsafeMutableRawPointer?>?
,你需要声明一个UnsafeMutableRawPointer?
.
而且,不幸的是,在很多情况下这可能不是一个关键问题,当将 Swift String
直接传递给 UnsafePointer<Int8>?
时,您需要根据 UTF-8 表示来计算长度.
你可能需要这样写:
func getClientKey() {
var keyVal: UnsafeMutableRawPointer? = nil
var len: UInt32 = 13 //<- this value is ignored though...
let status = SecKeychainFindGenericPassword(
nil,
UInt32(serviceName.utf8.count), serviceName, //### Use `utf8.count`
UInt32(accountName.utf8.count), accountName, //### Use `utf8.count`
&len, //### to pass `UnsafeMutablePointer<UInt32>?`, declare a variable of `UInt32`.
&keyVal, //### to pass `UnsafeMutablePointer<UnsafeMutableRawPointer?>?`, declare a variable of `UnsafeMutableRawPointer?`.
nil
)
if status == noErr {
let keyData = Data(bytes: keyVal!, count: Int(len))
//### As noted in the API reference of `SecKeychainFindGenericPassword`,
// "You should use the SecKeychainItemFreeContent function to free the memory pointed to by this parameter."
SecKeychainItemFreeContent(nil, keyVal)
print(keyData as NSData)
print(String(data: keyData, encoding: .utf8) ?? "?")
} else {
//You should not silently ignore erros...
print("Error: \(status)")
}
}