Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 从密钥链中的密钥对中提取公钥 问题是:检索公钥_Iphone_Objective C_Ios_Rsa_Ios5 - Fatal编程技术网

Iphone 从密钥链中的密钥对中提取公钥 问题是:检索公钥

Iphone 从密钥链中的密钥对中提取公钥 问题是:检索公钥,iphone,objective-c,ios,rsa,ios5,Iphone,Objective C,Ios,Rsa,Ios5,对于iPhone应用程序,我需要创建一个rsa密钥对,将其存储在密钥链中并检索公钥 幸运的是,苹果发布了一个示例,其中可以找到我需要的所有东西(SecKeyWrapper类、generateKeyPair函数和getPublicKeyBits函数) 但是在尝试使用这些函数之后,我总是为不同的密钥对获得相同的公钥输出(而不是为不同的密钥对获得不同的公钥位) my generateKeyPair和getPublicKeyBits函数的实现: 我首先通过调用generateKeyPairWithKey

对于iPhone应用程序,我需要创建一个rsa密钥对,将其存储在密钥链中并检索公钥

幸运的是,苹果发布了一个示例,其中可以找到我需要的所有东西(SecKeyWrapper类、generateKeyPair函数和getPublicKeyBits函数)

但是在尝试使用这些函数之后,我总是为不同的密钥对获得相同的公钥输出(而不是为不同的密钥对获得不同的公钥位)

my generateKeyPair和getPublicKeyBits函数的实现: 我首先通过调用generateKeyPairWithKeySizeInBits创建一个密钥对(这似乎工作得很好),然后我用getPublicKeyBits提取公钥位并将它们记录下来

- (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;
}