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函数的实现: 我首先通过调用generateKeyPairWithKey
- (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;
}
输出(“公共位”-部分(最后一行)始终相同:
2012-07-13 10:39:28.391[12279:707]开始生成密钥。。。
2012-07-13 10:39:39.376[12279:707]公钥
2012-07-13 10:39:39.381[12279:707]私钥
2012-07-13 10:39:39.397[12279:707]公共比特
公钥将包含两个组件:指数和模。您可以尝试此操作
获取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;
}
-(NSData*)getPublicKeyExp
{
NSData*pk=[self-getPublicKeyBits];
如果(pk==NULL)返回NULL;
int迭代器=0;
迭代器+++;//TYPE-bit-stream-mod+exp
[self-derEncodingGetSizeFrom:pk at:&迭代器];//总大小
迭代器+++;//类型-位流模式
int mod_size=[self-derEncodingGetSizeFrom:pk at:&迭代器];
迭代器+=模块大小;
迭代器+++;//类型-位流exp
int exp_size=[self-derEncodingGetSizeFrom:pk at:&迭代器];
返回[pk subdataWithRange:NSMakeRange(迭代器,exp_size)];
返回主键;
}
-(NSData*)getPublicKeyMod
{
NSData*pk=[self-getPublicKeyBits];
如果(pk==NULL)返回NULL;
int迭代器=0;
迭代器+++;//TYPE-bit-stream-mod+exp
[self-derEncodingGetSizeFrom:pk at:&迭代器];//总大小
迭代器+++;//类型-位流模式
int mod_size=[self-derEncodingGetSizeFrom:pk at:&迭代器];
返回[pk subdataWithRange:NSMakeRange(迭代器,mod_size)];
返回主键;
NSLog(@“公共大小:%d”,主键长度);
}
-(int)DeRecodingGetSizeFrom:(NSData*)buf at:(int*)迭代器
{
常量uint8_t*数据=[buf字节];
int itr=*迭代器;
int num_字节=1;
int-ret=0;
如果(数据[itr]>0x80){
num_bytes=数据[itr]-0x80;
itr++;
}
对于(int i=0;i
因此您的SecItemDelete代码无法按预期工作。如果要删除密钥链中的所有项目(显然是出于测试目的),应查看AdvancedURLConnections示例代码中的-[Credentials resetCredentials]
方法中的代码
在调试过程中,您可能会发现-dumpCredentials
方法非常方便
因此,SecItemDelete的问题意味着每次运行应用程序时,SecKeyGeneratePair都会生成一组新的密钥。这些密钥中的每一个都有相同的应用程序标记,这使得SecItemCopyMatching调用在-
getPublicKeyBits:
中返回的密钥不确定。事实证明,在当前的系统软件上,您总是会得到第一个密钥,因此您总是会得到相同的公钥位。对于生成公钥,您可以使用此链接感谢您的努力,但它并不能解决问题:公钥位保持不变,因此对于函数,指数和模将保持不变,我也不明白,你试过用那个链接吗
- (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;
}