使用Objective C在iOS中使用公钥加密或签名字符串 [英] encrypt or sign string with public key in iOS with Objective C
问题描述
我想用该密钥加密NSString。因为它的私钥,最好叫它签署一个NSString。
这可以在没有任何外部框架的情况下完成吗?
结果应该等同于php openssl_sign函数。
没有外部源或组件,您可以更轻松地解决这个问题。
我发现了如何分享它,以便我可以帮助别人。
- 您需要加载密钥文件SecKeyRef并安全地使用maxPlainLen
NSString * resourcePath = [[NSBundle mainBundle] pathForResource:privateKeyResourceName ofType:@p12];
NSData * p12Data = [NSData dataWithContentsOfFile:resourcePath];
NSMutableDictionary * options = [[NSMutableDictionary alloc] init];
SecKeyRef privateKeyRef = NULL;
//更改为您在此处使用的实际密码
[options setObject:@_ YOURPASSWORDHERE__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);
privateKey = privateKeyRef;
maxPlainLen = SecKeyGetBlockSize(privateKey) - 12;
- 您可以使用类别方法将NSString转换为SHA1
- (NSData *)toSha1AsData {
// PHP使用ASCII编码,而不是UTF
const char * s = [self cStringUsingEncoding:NSASCIIStringEncoding];
NSData * keyData = [NSData dataWithBytes:s length:strlen(s)];
//这是目的地
uint8_t摘要[CC_SHA1_DIGEST_LENGTH] = {0};
//这个函数执行哈希数据的无键SHA1哈希
CC_SHA1(keyData.bytes,keyData.length,digest);
//现在转换为NSData结构使其再次可用
NSData * out = [NSData dataWithBytes:摘要长度:CC_SHA1_DIGEST_LENGTH]
退出;
}
- 现在你可以用这种方法签署你的SHA1
(NSData *)signSha1Data :(NSData *)data {
size_t plainLen = [data length];
if(plainLen> maxPlainLen)
{
NSLog(@content(%ld)太长,必须<%ld,plainLen,maxPlainLen);
返回零;
}
void * plain = malloc(plainLen);
[data getBytes:plain
length:plainLen];
size_t cipherLen = 128; //当前RSA密钥长度设置为128字节
void * cipher = malloc(cipherLen);
OSStatus returnCode = SecKeyRawSign(privateKey,kSecPaddingPKCS1SHA1,
plain,plainLen,cipher,& cipherLen);
NSData * result = nil;
if(returnCode!= 0){
NSLog(@SecKeyEncrypt fail。错误代码:%ld,returnCode);
}
else {
result = [NSData dataWithBytes:cipher
length:cipherLen];
}
免费(普通);
免费(密码);
返回结果;
}
它工作得非常好,没有任何外部库。没有必要编译一些奇怪的openssl东西。
i have a private key. Text File that begins like "--- begin private key..."
i want to use that key to encrypt an NSString. since its the private key, better call it sign an NSString.
can this be done without any external frameworks?
the result should be equivalent to the php openssl_sign function.
You can solve this much easier with no external sources or components.
I found out how and wanted to share it so i may help others.
- You need to load the key file a SecKeyRef and safe the maxPlainLen as well
NSString *resourcePath = [[NSBundle mainBundle] pathForResource:privateKeyResourceName 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:@"_YOURPASSWORDHERE__" 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); privateKey = privateKeyRef; maxPlainLen = SecKeyGetBlockSize(privateKey) - 12;
- You can convert NSString with a category method to SHA1
- (NSData*)toSha1AsData { // PHP uses ASCII encoding, not UTF const char *s = [self cStringUsingEncoding:NSASCIIStringEncoding]; NSData *keyData = [NSData dataWithBytes:s length:strlen(s)]; // This is the destination uint8_t digest[CC_SHA1_DIGEST_LENGTH] = {0}; // This one function does an unkeyed SHA1 hash of your hash data CC_SHA1(keyData.bytes, keyData.length, digest); // Now convert to NSData structure to make it usable again NSData *out = [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH] return out; }
- Now you can sign your SHA1 with this method
(NSData *)signSha1Data:(NSData *)data {
size_t plainLen = [data length];
if (plainLen > maxPlainLen)
{
NSLog(@"content(%ld) is too long, must < %ld", plainLen, maxPlainLen);
return nil;
}
void *plain = malloc(plainLen);
[data getBytes:plain
length:plainLen];
size_t cipherLen = 128; // currently RSA key length is set to 128 bytes
void *cipher = malloc(cipherLen);
OSStatus returnCode = SecKeyRawSign(privateKey, kSecPaddingPKCS1SHA1,
plain, plainLen, cipher, &cipherLen);
NSData *result = nil;
if (returnCode != 0) {
NSLog(@"SecKeyEncrypt fail. Error Code: %ld", returnCode);
}
else {
result = [NSData dataWithBytes:cipher
length:cipherLen];
}
free(plain);
free(cipher);
return result;
}
It works very well and without any external libs. There is no need to compile some wierd openssl stuff.
这篇关于使用Objective C在iOS中使用公钥加密或签名字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!