Objective-C / C 从 SecKeyRef 中提取私钥(模数)
Objective-C / C pulling private key (modulus) from SecKeyRef
我需要一种干净的方法来提取我的服务器 public 密钥并将其与本地数据进行比较,以防止将来密钥过期/更新,但我似乎无法获得256位密钥或表示为比较有用的数据...
这是我目前所拥有的...
-(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!");
}
我参加了 Apples Crypto Exercise 并获得了以下...
- (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;
}
这个 return 是 270 字节而不是预期的 256.. 我无法用一种方式将它与我的 localData
进行比较
本地密钥是 512 字节的 ASCII(为什么?)45323636 32323330 派生密钥是 270 字节的 UTF8 223b70a0 56f28f68
首先我需要从 getPublicKeyBitsFromKey
得到 256 个字节,我还需要以相同的方式表达我的数据以进行比较。
还值得注意的是
NSString *keyString = [NSString stringWithUTF8String:[keyData bytes]];
和
NSString *keyString = [[NSString alloc] initWithBytes:[keyData bytes] length:[keyData length] encoding:NSUTF8StringEncoding];
return(空)
NSString *keyString = [NSString stringWithCharacters:[keyData bytes] length:[keyData length]];
甚至不记录
如有任何帮助,我们将不胜感激,在此先致谢。
我通过在本地复制 .der 并固定它的 public 键来解决这个问题。
-(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;
}
我需要一种干净的方法来提取我的服务器 public 密钥并将其与本地数据进行比较,以防止将来密钥过期/更新,但我似乎无法获得256位密钥或表示为比较有用的数据...
这是我目前所拥有的...
-(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!");
}
我参加了 Apples Crypto Exercise 并获得了以下...
- (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;
}
这个 return 是 270 字节而不是预期的 256.. 我无法用一种方式将它与我的 localData
本地密钥是 512 字节的 ASCII(为什么?)45323636 32323330 派生密钥是 270 字节的 UTF8 223b70a0 56f28f68
首先我需要从 getPublicKeyBitsFromKey
得到 256 个字节,我还需要以相同的方式表达我的数据以进行比较。
还值得注意的是
NSString *keyString = [NSString stringWithUTF8String:[keyData bytes]];
和
NSString *keyString = [[NSString alloc] initWithBytes:[keyData bytes] length:[keyData length] encoding:NSUTF8StringEncoding];
return(空)
NSString *keyString = [NSString stringWithCharacters:[keyData bytes] length:[keyData length]];
甚至不记录
如有任何帮助,我们将不胜感激,在此先致谢。
我通过在本地复制 .der 并固定它的 public 键来解决这个问题。
-(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;
}