从SecKeyRef提取Objective-C/C私钥(模数) [英] Objective-C / C pulling private key (modulus) from SecKeyRef

查看:98
本文介绍了从SecKeyRef提取Objective-C/C私钥(模数)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一种干净的方法来拔出服务器的公共密钥,并将其与本地数据进行比较,以防将来出现过期/更新的密钥,但是我似乎无法获得256位密钥或将其表达出来作为比较的有用数据...

I need a clean way to pull out my servers public key and compare it to local data in order to defend against expiring / renewed keys in the future, but I can't seem to get at the 256 bit key or express it as useful data for comparison...

这是我到目前为止所拥有的...

Here's what I have so far...

-(BOOL)trustCertFromChallenge:(NSURLAuthenticationChallenge *)challenge
{

    SecTrustResultType trustResult;
    SecTrustRef trust = challenge.protectionSpace.serverTrust;
    OSStatus status = SecTrustEvaluate(trust, &trustResult);


    NSString *localKey = @"MY_PUBLIC_KEY";
    NSData *localKeyData = [localKey dataUsingEncoding:NSUTF8StringEncoding];

    SecCertificateRef serverCertificate = SecTrustGetCertificateAtIndex(trust, 0);
    SecKeyRef key = SecTrustCopyPublicKey(trust);

    DLog(@"Cert: %@  Key:%@",serverCertificate,key);

    // this prints the correct cert information and key information
    // for clarity....
    // Key: <SecKeyRef algorithm id: 1, key type: RSAPublicKey, version: 3, block size: 2048 bits, exponent: {hex: 10001, decimal: 65537}, modulus: MY_PUBLIC_KEY, addr: 0x7fa78b80bc00>

    // so far so good.. now for grabbing the key
    NSData *keyData = [self getPublicKeyBitsFromKey:key];

    DLog(@"Local: %@ - %li Key: %@ - %li",[localKeyData description],[localKeyData length],[keyData description],[keyData length]);


    if ([localKeyData isEqualToData:keyData])
        DLog(@"ITS THE SAME!");
    else
        DLog(@"NOT THE SAME!");

}

我参加了苹果加密演习,并了解了以下内容...

I've had a go with Apples Crypto Exercise and got to the following...

- (NSData *)getPublicKeyBitsFromKey:(SecKeyRef)givenKey {

    static const uint8_t publicKeyIdentifier[] = "com.mydomain.publickey";
    NSData *publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)];

    OSStatus sanityCheck = noErr;
    NSData *publicKeyBits = nil;

    NSMutableDictionary *queryPublicKey = [[NSMutableDictionary alloc] init];
    [queryPublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
    [queryPublicKey setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag];
    [queryPublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];

    // Temporarily add key to the Keychain, return as data:
    NSMutableDictionary * attributes = [queryPublicKey mutableCopy];
    [attributes setObject:(__bridge id)givenKey forKey:(__bridge id)kSecValueRef];
    [attributes setObject:@YES forKey:(__bridge id)kSecReturnData];
    CFTypeRef result;
    sanityCheck = SecItemAdd((__bridge CFDictionaryRef) attributes, &result);
    if (sanityCheck == errSecSuccess) {
        publicKeyBits = CFBridgingRelease(result);

        // Remove from Keychain again:
        (void)SecItemDelete((__bridge CFDictionaryRef) queryPublicKey);
    }

    return publicKeyBits;
}

这将返回270个字节,而不是预期的256个字节..我无法以将其与我的localData

This returns 270 bytes instead of the expected 256.. which I can't express in a way to compare it to my localData

本地密钥是512字节的ASCII(为什么)45323636 32323330,派生密钥是270字节的UTF8 223b70a0 56f28f68

The local key is 512 bytes of ASCII (why?) 45323636 32323330 and the derived key is 270 bytes of UTF8 223b70a0 56f28f68

首先,我需要从getPublicKeyBitsFromKey中获取256个字节,并且还需要以相同的方式表示我的数据以进行比较.

First I need to get to 256 bytes from getPublicKeyBitsFromKey and I also need to express my data in the same manner to compare it.

值得注意的是

NSString *keyString = [NSString stringWithUTF8String:[keyData bytes]];

NSString *keyString = [[NSString alloc] initWithBytes:[keyData bytes] length:[keyData length] encoding:NSUTF8StringEncoding];

返回(空)

NSString *keyString = [NSString stringWithCharacters:[keyData bytes] length:[keyData length]];

甚至没有登录

任何帮助将不胜感激,所以在此先感谢.

Any help would be greatly appreciated, so thanks in advance.

推荐答案

我通过在本地拥有.der的副本并将其固定为公钥来解决了这个问题.

I solved this by having a copy of the .der locally and pinning just it's public key.

-(BOOL)trustCertFromChallenge:(NSURLAuthenticationChallenge *)challenge
{
    SecTrustResultType trustResult;
    SecTrustRef trust = challenge.protectionSpace.serverTrust;
    OSStatus status = SecTrustEvaluate(trust, &trustResult);

    //DLog(@"Failed: %@",error.localizedDescription);
    //DLog(@"Status: %li | Trust: %@ - %li",(long)status,trust,(long)trustResult);

    if (status == 0 && (trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed)) {

        SecKeyRef serverKey = SecTrustCopyPublicKey(trust);

        NSString *certPath = [[NSBundle mainBundle] pathForResource:@"MYCert" ofType:@"der"];
        NSData *certData = [NSData dataWithContentsOfFile:certPath];
        SecCertificateRef localCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData);

        SecKeyRef localKey = NULL;
        SecTrustRef localTrust = NULL;
        SecCertificateRef certRefs[1] = {localCertificate};
        CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, (void *)certRefs, 1, NULL);
        SecPolicyRef policy = SecPolicyCreateBasicX509();
        OSStatus status = SecTrustCreateWithCertificates(certArray, policy, &localTrust);

        if (status == errSecSuccess)
            localKey = SecTrustCopyPublicKey(localTrust);

        CFRelease(localTrust);
        CFRelease(policy);
        CFRelease(certArray);

         if (serverKey != NULL && localKey != NULL && [(__bridge id)serverKey isEqual:(__bridge id)localKey])
            return YES;
        else
            return NO;
    }

    //DLog(@"Failed: %@",error.localizedDescription);

    return NO;
}

这篇关于从SecKeyRef提取Objective-C/C私钥(模数)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆