我正在尝试使用RSA在HTTP标头内签署一个必须传递给Web服务的令牌 - 要求是我应该使用自己的私钥加密并给他们我的公钥。这纯粹用于验证消息是由我发送的。
我知道很多类似的问题,但我今天早上到目前为止已经进行了很多次尝试,而且我仍然没有接近我认为会是微不足道的。
我可以找到许多使用RSA和使用公钥加密的示例,但我的要求是我使用私钥进行签名。
看起来(从最初的尝试)苹果样本安全代码和从中借用的大多数其他示例总是使用钥匙串生成私钥/公钥对 - 我更喜欢使用OpenSSL生成我的密钥,所以我可以分发公钥给我的客户。
我已设法生成一些密钥,看起来我可以使用此代码加载私钥(道歉,我不记得源代码,因为我已经将实现混合了几个小时):
-(SecKeyRef) getPrivateKeyRef {
NSString *resourcePath = [[NSBundle mainBundle] pathForResource:@"rsaPrivate" ofType:@"p12"];
NSData *p12Data = [NSData dataWithContentsOfFile:resourcePath];
NSMutableDictionary * options = [[NSMutableDictionary alloc] init];
SecKeyRef privateKeyRef = NULL;
//change to the actual password you used here
[options setObject:@"xxxx" forKey:(__bridge id)kSecImportExportPassphrase];
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
OSStatus securityError = SecPKCS12Import((__bridge CFDataRef) p12Data,
(__bridge CFDictionaryRef)options, &items);
if (securityError == noErr && CFArrayGetCount(items) > 0) {
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
SecIdentityRef identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict,
kSecImportItemIdentity);
securityError = SecIdentityCopyPrivateKey(identityApp, &privateKeyRef);
if (securityError != noErr) {
privateKeyRef = NULL;
}
}
CFRelease(items);
return privateKeyRef;
}
似乎给我一个有效的SecKeyRef
,但我不知道如何使用它来签署NSString
。
似乎有很多方法可以解决这个问题(构建OpenSSL并链接到它,使用Apple的钥匙串方法,在GitHub上使用部分完整的库)但我一直走到死胡同 - 这将是理想的适当的,完整的解决方案。
有些事情:
NSString* signedString = [rsaHelper signString: @"Hello, World!" WithPrivateKey:@"rsaPrivate.p12"];
给定一个用公钥加密的字符串:
NSString* decryptedString = [rsaHelper decryptString: @"DK5tkgkfjkJJft=" WithPrivateKey:@"rsaPrivate.p12"];
会很有价值!请注意,我并不害怕以任何方式自己编写此代码,但是会欣赏正确的方向: - )