Iphone 从密钥链中的密钥对中提取公钥 问题是:检索公钥
对于iPhone应用程序,我需要创建一个rsa密钥对,将其存储在密钥链中并检索公钥 幸运的是,苹果发布了一个示例,其中我需要的所有东西都可以找到SecKeyWrapper类、generateKeyPair函数和getPublicKeyBits函数 但是在尝试使用这些函数之后,我总是为不同的密钥对获得相同的公钥输出,而不是为不同的密钥对获得不同的公钥位 my generateKeyPair和getPublicKeyBits函数的实现: 我首先通过调用generateKeyPairWithKeySizeInBits创建一个密钥对,它似乎工作得很好,然后我用getPublicKeyBits提取公钥位并将它们记录下来Iphone 从密钥链中的密钥对中提取公钥 问题是:检索公钥,iphone,objective-c,ios,rsa,ios5,Iphone,Objective C,Ios,Rsa,Ios5,对于iPhone应用程序,我需要创建一个rsa密钥对,将其存储在密钥链中并检索公钥 幸运的是,苹果发布了一个示例,其中我需要的所有东西都可以找到SecKeyWrapper类、generateKeyPair函数和getPublicKeyBits函数 但是在尝试使用这些函数之后,我总是为不同的密钥对获得相同的公钥输出,而不是为不同的密钥对获得不同的公钥位 my generateKeyPair和getPublicKeyBits函数的实现: 我首先通过调用generateKeyPairWithKeySi
- (void) generateKeyPairWithKeySizeInBits:(int)bits withPublicIdentifier:(NSString *)publicIdentifier andPrivateIdentifier:(NSString *)privateIdentifier
{
NSLog(@"begin generating key...");
OSStatus status = noErr;
NSMutableDictionary* privateKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary* publicKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary* keyPairAttr = [[NSMutableDictionary alloc] init];
NSData* publicTag = [publicIdentifier dataUsingEncoding:NSUTF8StringEncoding];
NSData* privateTag = [privateIdentifier dataUsingEncoding:NSUTF8StringEncoding];
SecKeyRef publicKey = NULL;
SecKeyRef privateKey = NULL;
[keyPairAttr setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id) kSecAttrKeyType];
[keyPairAttr setObject:[NSNumber numberWithInt:bits] forKey:(__bridge id) kSecAttrKeySizeInBits];
[privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id) kSecAttrIsPermanent];
[privateKeyAttr setObject:privateTag forKey:(__bridge id) kSecAttrApplicationTag];
[publicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecAttrIsPermanent];
[publicKeyAttr setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag];
[keyPairAttr setObject:privateKeyAttr forKey:(__bridge id)kSecPrivateKeyAttrs];
[keyPairAttr setObject:publicKeyAttr forKey:(__bridge id)kSecPublicKeyAttrs];
SecItemDelete((__bridge CFDictionaryRef)keyPairAttr);
status = SecKeyGeneratePair((__bridge CFDictionaryRef) keyPairAttr, &publicKey, &privateKey);
if(status != noErr){
NSLog(@"status = %@",status);
}
if(publicKey){
NSLog(@"public key %@",publicKey);
}
if(privateKey){
NSLog(@"private key %@",privateKey);
}
[self getPublicKeyBits:publicIdentifier];
}
- (NSData *)getPublicKeyBits: (NSString*) publicKeyIdentifier {
OSStatus sanityCheck = noErr;
NSData * publicKeyBits = nil;
CFTypeRef pk;
NSMutableDictionary * queryPublicKey = [[NSMutableDictionary alloc] init];
NSData* publicTag = [publicKeyIdentifier dataUsingEncoding:NSUTF8StringEncoding];
// Set the public key query dictionary.
[queryPublicKey setObject:(__bridge_transfer id)kSecClassKey forKey:(__bridge_transfer id)kSecClass];
[queryPublicKey setObject:publicTag forKey:(__bridge_transfer id)kSecAttrApplicationTag];
[queryPublicKey setObject:(__bridge_transfer id)kSecAttrKeyTypeRSA forKey:(__bridge_transfer id)kSecAttrKeyType];
[queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge_transfer id)kSecReturnData];
// Get the key bits.
sanityCheck = SecItemCopyMatching((__bridge_retained CFDictionaryRef)queryPublicKey, &pk);
if (sanityCheck != noErr)
{
publicKeyBits = nil;
}
publicKeyBits = (__bridge_transfer NSData*)pk;
NSLog(@"public bits %@",publicKeyBits);
return publicKeyBits;
}
输出公共位部分最后一行始终相同:
公钥将包含两个组件:指数和模。您可以尝试此操作 获取PublickeyBits方法后
- (NSData *)getPublicKeyExp
{
NSData* pk = [self getPublicKeyBits];
if (pk == NULL) return NULL;
int iterator = 0;
iterator++; // TYPE - bit stream - mod + exp
[self derEncodingGetSizeFrom:pk at:&iterator]; // Total size
iterator++; // TYPE - bit stream mod
int mod_size = [self derEncodingGetSizeFrom:pk at:&iterator];
iterator += mod_size;
iterator++; // TYPE - bit stream exp
int exp_size = [self derEncodingGetSizeFrom:pk at:&iterator];
return [pk subdataWithRange:NSMakeRange(iterator, exp_size)];
return pk;
}
- (NSData *)getPublicKeyMod
{
NSData* pk = [self getPublicKeyBits];
if (pk == NULL) return NULL;
int iterator = 0;
iterator++; // TYPE - bit stream - mod + exp
[self derEncodingGetSizeFrom:pk at:&iterator]; // Total size
iterator++; // TYPE - bit stream mod
int mod_size = [self derEncodingGetSizeFrom:pk at:&iterator];
return [pk subdataWithRange:NSMakeRange(iterator, mod_size)];
return pk;
NSLog(@"public size: %d",pk.length);
}
- (int)derEncodingGetSizeFrom:(NSData*)buf at:(int*)iterator
{
const uint8_t* data = [buf bytes];
int itr = *iterator;
int num_bytes = 1;
int ret = 0;
if (data[itr] > 0x80) {
num_bytes = data[itr] - 0x80;
itr++;
}
for (int i = 0 ; i < num_bytes; i++)
ret = (ret * 0x100) + data[itr + i];
*iterator = itr + num_bytes;
return ret;
}
因此,您的SecItemDelete代码无法按预期工作。显然,如果出于测试目的您想删除密钥链中的所有项目,您应该查看AdvancedURLConnections示例代码中的-[Credentials resetCredentials]方法中的代码 在调试过程中,您可能还会发现-dumpCredentials方法很方便
因此,SecItemDelete的问题意味着每次运行应用程序时,SecKeyGeneratePair都会生成一组新的密钥。这些键中的每一个都有相同的应用程序标记,这使得它无法确定-getPublicKeyBits:中的SecItemCopyMatching调用返回的键。事实证明,在当前的系统软件上,您总是会得到第一个密钥,因此您总是会得到相同的公钥位。对于生成公钥,您可以使用此链接感谢您的努力,但它并不能解决问题:公钥位保持不变,因此对于函数,指数和模将保持不变,我也不明白,你试过用那个链接吗
- (NSData *)getPublicKeyExp
{
NSData* pk = [self getPublicKeyBits];
if (pk == NULL) return NULL;
int iterator = 0;
iterator++; // TYPE - bit stream - mod + exp
[self derEncodingGetSizeFrom:pk at:&iterator]; // Total size
iterator++; // TYPE - bit stream mod
int mod_size = [self derEncodingGetSizeFrom:pk at:&iterator];
iterator += mod_size;
iterator++; // TYPE - bit stream exp
int exp_size = [self derEncodingGetSizeFrom:pk at:&iterator];
return [pk subdataWithRange:NSMakeRange(iterator, exp_size)];
return pk;
}
- (NSData *)getPublicKeyMod
{
NSData* pk = [self getPublicKeyBits];
if (pk == NULL) return NULL;
int iterator = 0;
iterator++; // TYPE - bit stream - mod + exp
[self derEncodingGetSizeFrom:pk at:&iterator]; // Total size
iterator++; // TYPE - bit stream mod
int mod_size = [self derEncodingGetSizeFrom:pk at:&iterator];
return [pk subdataWithRange:NSMakeRange(iterator, mod_size)];
return pk;
NSLog(@"public size: %d",pk.length);
}
- (int)derEncodingGetSizeFrom:(NSData*)buf at:(int*)iterator
{
const uint8_t* data = [buf bytes];
int itr = *iterator;
int num_bytes = 1;
int ret = 0;
if (data[itr] > 0x80) {
num_bytes = data[itr] - 0x80;
itr++;
}
for (int i = 0 ; i < num_bytes; i++)
ret = (ret * 0x100) + data[itr + i];
*iterator = itr + num_bytes;
return ret;
}