我是新来的Objective C & iOS编程。Objective C:无法从PEM私钥获取SecKeyRef
我正在使用使用openssl生成的简单的公钥/私钥(PEM格式)来加密和解密需要在服务器和客户端之间交换的数据。我在Java服务器&客户端成功运行。
当我使用Java中的公钥加密数据并使用Objective C/iOS中的私钥解密时,麻烦就开始了。我查了几个例子,并将一些代码放在一起,但是当我通过私钥调用SecKeyRef的一部分时,始终调用SecItemCopyMatching时出现错误-25300。
顺便说一句,这里没有涉及的证书,它只是普通的密钥。 以下是我在做什么:
- 阅读PEM私钥和Base64解码。
- 使用SecItemCopyMatching从已解码的字符串中生成一个SecKeyRef。
- 使用SecKeyDecrypt解密。
我的问题是步骤#2返回-25300状态(errSecItemNotFound -25300
的项目不能被发现。可用在IOS 2.0和更高。)
这是我的用于产生代码SecKeyRef:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSString *challenge = @"2KFqc46DNSWrizzv69lJN25o62xEYQw/QLcMiT2V1XLER9uJbOu+xH2qgTuNWa1HZ9SW3Lq+HovtkhFmjmf08QkVQohHmxCJXVyCgVhPBleScAgQ8AoP3tmV0RqGb2mJrb19ybeYP7uZ2piVtF4cRwU1gO3VTooCUK3cX4wS7Tc=";
NSLog(@"challenge, %@", challenge);
NSData *incomingData = [self base64DataFromString:challenge];
uint8_t *challengeBuffer = (uint8_t*)[incomingData bytes];
NSLog(@"challengeBuffer: %s", challengeBuffer);
[self decryptWithPrivateKey:challengeBuffer];
free(challengeBuffer);
return YES;
}
// Generate a SecKeyRef from the private key in the private.pem file.
- (SecKeyRef)getPrivateKeyRef {
NSString *startPrivateKey = @"-----BEGIN RSA PRIVATE KEY-----";
NSString *endPrivateKey = @"-----END RSA PRIVATE KEY-----";
NSString* path = [[NSBundle mainBundle] pathForResource:@"private"
ofType:@"pem"];
NSString* content = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:NULL];
NSLog(@"Private Key: %@", content);
NSString *privateKey;
NSScanner *scanner = [NSScanner scannerWithString:content];
[scanner scanUpToString:startPrivateKey intoString:nil];
[scanner scanString:startPrivateKey intoString:nil];
[scanner scanUpToString:endPrivateKey intoString:&privateKey];
NSData *privateTag = [self dataWithBase64EncodedString:privateKey];
NSLog(@"Decoded String: %@", privateTag);
OSStatus status = noErr;
SecKeyRef privateKeyReference = NULL;
NSMutableDictionary * queryPrivateKey = [[NSMutableDictionary alloc] init];
// Set the private key query dictionary.
[queryPrivateKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[queryPrivateKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
[queryPrivateKey setObject:privateTag forKey:(__bridge id)kSecAttrApplicationTag];
[queryPrivateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
//[queryPrivateKey setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnRef];
// Get the key.
status = SecItemCopyMatching((__bridge CFDictionaryRef)queryPrivateKey, (CFTypeRef *)&privateKeyReference);
NSLog(@"status: %ld", status);
if(status != noErr)
{
privateKeyReference = NULL;
}
return privateKeyReference;
}
// Decrypt data
- (void)decryptWithPrivateKey:(uint8_t *)cipherBuffer {
OSStatus status = noErr;
SecKeyRef privateKeyRef = [self getPrivateKeyRef];
size_t plainBufferSize = SecKeyGetBlockSize(privateKeyRef);
uint8_t *plainBuffer = malloc(plainBufferSize);
size_t cipherBufferSize = strlen((char *)cipherBuffer);
NSLog(@"decryptWithPrivateKey: length of input: %lu", cipherBufferSize);
// Error handling
status = SecKeyDecrypt(privateKeyRef,
PADDING,
cipherBuffer,
cipherBufferSize,
&plainBuffer[0],
&plainBufferSize
);
NSLog(@"decryption result code: %ld (size: %lu)", status, plainBufferSize);
NSLog(@"FINAL decrypted text: %s", plainBuffer);
}
现在我已经打破我的头几天,我觉得我需要在这里得到一些帮助。任何一个任何指针?我可以花更多时间获得iOS提供的Crypto领域知识和支持,但我根本不做任何iOS编程,这是一次性的。
我只是需要一些方向,我可以努力使其工作。
TIA。
你有没有得到这个工作?同样的问题。 –
我仍然面对同样的情况。你有这个工作吗? –
您只能使用'SecItemCopyMatching'来检索以前添加到钥匙串的项目。由于您没有添加任何内容,因此无法检索。 – orkoden