2012-07-02 23 views
3

SecKeyRef始终为空,即使我没有从任何状态中收到任何错误。我最初认为这是一个弧形问题,但演员表看起来没问题。任何帮助,将不胜感激。iOS钥匙串问题。 SecKeyRef始终为空SecItemCopyMatching()结果为

+ (SecKeyRef)addPublicKey:(NSString *)key withTag:(NSString *)tag 
    { 
     // This will be base64 encoded, decode it. 
     NSData *d_key = [key dataUsingEncoding:NSUTF8StringEncoding]; 

     if (d_key == nil) return (FALSE); 

     NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]]; 

     // Delete any old lingering key with the same tag 
     NSMutableDictionary *publicKey = [[NSMutableDictionary alloc] init]; 
     [publicKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass]; 
     [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; 
     [publicKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag]; 
     SecItemDelete((__bridge CFDictionaryRef)publicKey); 

     CFTypeRef persistKey = nil; 

     // Add persistent version of the key to system keychain 
     [publicKey setObject:d_key forKey:(__bridge id)kSecValueData]; 
     [publicKey setObject:(__bridge id) kSecAttrKeyClassPublic forKey:(__bridge id)kSecAttrKeyClass]; 
     [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnPersistentRef]; 

     OSStatus secStatus = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey); 

     NSLog(@"OSStatus = %ld", secStatus); // Always returns no error = 0 

     if (persistKey != nil) CFRelease(persistKey); 

     if ((secStatus != noErr) && (secStatus != errSecDuplicateItem)) { 
      return nil; 
     } 

     // Now fetch the SecKeyRef version of the key 
     SecKeyRef keyRef; 

     [publicKey removeObjectForKey:(__bridge id)kSecValueData]; 
     [publicKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef]; 
     [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef]; 
     [publicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; 


     secStatus = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey, (CFTypeRef *)&keyRef); 

     NSLog(@"secStatus = %ld", secStatus); // Always returns no error = 0 

     return keyRef; // Always null! 
    } 

回答

0

我正在研究类似的东西,并且遇到了这篇文章。我试过你的代码,它对我来说工作得很好,所以我认为它是正确的。我怀疑关键数据是错误的。我尝试了通过这种方法喂养坏的关键数据,它给了我一个像你说的那样的空引用。我使用这个 -

https://github.com/meinside/iphonelib/blob/master/security/CryptoUtil.m#L67

请注意有几个未决引入请求的建设从一模数和指数公钥(ASN.1 DER)。

我想也许你应该尝试一个.cer文件或者用openssl生成一个rsa密钥,并使用CryptoUtil的模数和指数。

-1

我也正在面对这个问题,最后可以通过以正确的格式(ASN.1 DER格式)发送输入数据(关键参数)来解决它。下面的方法没有产生任何密钥,尽管没有错误,状态码0就像@reedjsmith提到的那样 - 当数据以任何其他格式(普通的base64编码数据)发送或者使用除PKCS#1填充以外的任何其他内容生成的密钥数据。

  • (SecKeyRef)addPublicKey:(的NSString *)键withTag:(的NSString *)标记
+0

这是一个问题,而不是答案。如果您无法发表评论,如果您以问题的形式发布答案,您将无法很快获得评论。 – Idris

0

我意识到这是一个老问题,但我有同样的问题,所以我要添加这里的发现。也许它会帮助别人。

首先,在你的情况下,它看起来不像你正在解码RSA密钥。你有解码base64编码密钥的注释,但是你只需将它转换为一个NSData对象。你必须base64解码RSA密钥。

第二,请确保您将标题和任何新行剥离出密钥字符串。

然后base64解码字符串并将其转换为NSData以用于kSecValueData。

在我的情况下,我正在将密钥转换为NSData,然后将其解码...不知道这是否是解码器的问题,但我一直得到一个空的secKeyRef。我的解码器只有当我解码密钥字符串,然后转换为NSData时工作。

那一条信息让我暂时停滞不前。