即使我没有从任何状态中获得任何错误,SecKeyRef也始终为null。我最初认为这是一个弧问题,但演员表看起来不错。任何帮助将不胜感激。
+ (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 :(得分:0)
我正在研究类似的事情并且发现了这篇文章。我试用了你的代码,它对我来说很好,所以我认为它是正确的。我怀疑关键数据是错误的。我尝试通过这种方法提供坏密钥数据,它给了我一个像你所说的空引用。我正在使用这个 -
从模数和指数构建公钥(ASN.1 DER)https://github.com/meinside/iphonelib/blob/master/security/CryptoUtil.m#L67
请注意,有几个待处理的拉取请求。
我想也许您应该尝试使用.ss文件或使用openssl生成rsa密钥,并将模数和指数与CryptoUtil一起使用。
答案 1 :(得分:0)
我意识到这是一个老问题,但我有同样的问题,所以我在这里添加我的发现。也许它会帮助别人。
首先,在您的情况下,它看起来并不像您正在解码RSA密钥。你有注释解码base64编码的密钥,但你只需将其转换为NSData对象。你必须使用base64解码RSA密钥。
第二,确保从标题字符串中删除标题和任何新行。
然后base64解码字符串并将其转换为NSData以用于kSecValueData。
在我的情况下,我正在将密钥转换为NSData然后解码它...不确定这是否是解码器的问题,但我一直得到一个空的secKeyRef。我的解码器只在解码密钥字符串然后转换为NSData时才起作用。
有一条信息让我退了一会儿。
答案 2 :(得分:-1)
我也面临这个问题,最后可以通过以ASN.1 DER格式的正确格式发送输入数据(密钥参数)来解决它。尽管没有错误和状态代码0,但是下面的方法没有产生任何密钥,就像@reedjsmith所提到的那样 - 当数据以任何其他格式(普通base64编码数据)或使用除PKCS#1填充之外的任何其他内容生成的密钥数据发送时。