ios – 在Swift中无法检索存储在Objective-C中的Keychain的值?

ios – 在Swift中无法检索存储在Objective-C中的Keychain的值?,第1张

概述我遇到了钥匙扣最棘手的问题.我有一个使用加密Realm数据库的现有应用程序,加密密钥正在保存到Keychain,根据Realm的代码示例 here. - (NSData *)getKey { // Identifier for our keychain entry - should be unique for your application static const uint8_ 我遇到了钥匙扣最棘手的问题.我有一个使用加密Realm数据库的现有应用程序,加密密钥正在保存到Keychain,根据Realm的代码示例 here.

- (NSData *)getKey {    // IDentifIEr for our keychain entry - should be unique for your application    static const uint8_t kKeychainIDentifIEr[] = "io.Realm.EncryptionExampleKey";    NSData *tag = [[NSData alloc] initWithBytesNocopy:(voID *)kKeychainIDentifIEr                                               length:sizeof(kKeychainIDentifIEr)                                         freeWhenDone:NO];    // First check in the keychain for an existing key    NSDictionary *query = @{(__brIDge ID)kSecclass: (__brIDge ID)kSecclassKey,(__brIDge ID)kSecAttrApplicationTag: tag,(__brIDge ID)kSecAttrKeySizeInBits: @512,(__brIDge ID)kSecReturnData: @YES};    CFTypeRef dataRef = NulL;    Osstatus status = SecItemcopyMatching((__brIDge CFDictionaryRef)query,&dataRef);    if (status == errSecSuccess) {        return (__brIDge NSData *)dataRef;    }    // No pre-existing key from this application,so generate a new one    uint8_t buffer[64];    status = SecRandomcopyBytes(kSecRandomDefault,64,buffer);    NSAssert(status == 0,@"Failed to generate random bytes for key");    NSData *keyData = [[NSData alloc] initWithBytes:buffer length:sizeof(buffer)];    // Store the key in the keychain    query = @{(__brIDge ID)kSecclass: (__brIDge ID)kSecclassKey,(__brIDge ID)kSecValueData: keyData};    status = SecItemAdd((__brIDge CFDictionaryRef)query,NulL);    NSAssert(status == errSecSuccess,@"Failed to insert new key in the keychain");    return keyData;}

我正在努力将此应用程序转换为Swift,我正在尝试使用Realm的快速代码示例检索存储在Keychain中的加密密钥

func getKey() -> NSData {    // IDentifIEr for our keychain entry - should be unique for your application    let keychainIDentifIEr = "io.Realm.EncryptionExampleKey"    let keychainIDentifIErData = keychainIDentifIEr.data(using: String.EnCoding.utf8,allowLossyConversion: false)!    // First check in the keychain for an existing key    var query: [Nsstring: AnyObject] = [        kSecclass: kSecclassKey,kSecAttrApplicationTag: keychainIDentifIErData as AnyObject,kSecAttrKeySizeInBits: 512 as AnyObject,kSecReturnData: true as AnyObject    ]    // To avoID Swift optimization BUG,should use withUnsafeMutablePointer() function to retrIEve the keychain item    // See also: https://stackoverflow.com/questions/24145838/querying-ios-keychain-using-swift/27721328#27721328    var dataTypeRef: AnyObject?    var status = withUnsafeMutablePointer(to: &dataTypeRef) { SecItemcopyMatching(query as CFDictionary,UnsafeMutablePointer(
static const uint8_t kKeychainIDentifIEr[] = "io.Realm.EncryptionExampleKey";NSData *tag = [[NSData alloc] initWithBytesNocopy:(voID *)kKeychainIDentifIEr                                           length:sizeof(kKeychainIDentifIEr) - 1 // <- Truncate last char                                     freeWhenDone:NO];
)) } if status == errSecSuccess { return dataTypeRef as! NSData } // No pre-existing key from this application,so generate a new one let keyData = NSMutableData(length: 64)! let result = SecRandomcopyBytes(kSecRandomDefault,keyData.mutableBytes.bindMemory(to: UInt8.self,capacity: 64)) assert(result == 0,"Failed to get random bytes") // Store the key in the keychain query = [ kSecclass: kSecclassKey,kSecValueData: keyData ] status = SecItemAdd(query as CFDictionary,nil) assert(status == errSecSuccess,"Failed to insert the new key in the keychain") return keyData}

现在的问题是Swift代码无法通过Objective-C代码返回存储在Keychain中的值.我在创建keychainIDentifIErData时尝试修改Swift代码以使用NSData而不是Data,但我无法让它工作.

在我的实际项目中,SecItemcopyMatching调用返回成功状态,但dataTypeRef始终为nil,在强制转换为Data时崩溃.在我为此创建的一个小测试项目中,找不到密钥,这似乎表明问题在于将keychainIDentifIEr转换为keychainIDentifIErData,但我现在找不到任何信息如何在语言之间保持一致.

我发现的一个线索是将标签/ keychainIDentifIErData打印到控制台,在Obj-c中它是
< 696f2e52 65616c6d 2e456e63 72797074 696f6e45 78616d70 6c654b65 7900>
在斯威夫特的哪个地方
< 696f2e52 65616c6d 2e456e63 72797074 696f6e45 78616d70 6c654b65 79>

这表明密钥在语言之间不匹配,但后来我不明白为什么SecItemcopyMatching会返回成功.

有没有人对如何检索我的加密密钥有任何见解?提前致谢 :)

解决方法 Objective-C keychainIDentifIEr被创建为C字符串,它始终以null结尾. null终止符与字符一起编码,导致您注意到的尾随’00’被附加到结果中. Swift字符串不是以null结尾的.

要实现奇偶校验,请在创建Objective-C标识符时省略最后一个字符:

Nsstring *keychainIDentifIEr = @"io.Realm.EncryptionExampleKey";NSData *tag = [keychainIDentifIEr dataUsingEnCoding:NSUTF8StringEnCoding];

或者,使用Nsstring在Objective-C中表示您的标识符:

总结

以上是内存溢出为你收集整理的ios – 在Swift中无法检索存储在Objective-C中的Keychain的值?全部内容,希望文章能够帮你解决ios – 在Swift中无法检索存储在Objective-C中的Keychain的值?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1063679.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-26
下一篇2022-05-26

发表评论

登录后才能评论

评论列表(0条)

    保存