PRN*_*ios 6 encryption rsa objective-c x509 ios
我需要使用X.509 RSA公钥/私钥对来实现加密/解密.
到目前为止,我有一些我认为可用于加密的东西,但我无法解密检查.我尝试的所有内容都有读取私钥的问题.
.der和a .pem)openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem -days 3650
Run Code Online (Sandbox Code Playgroud)
+ (NSData *) RSAEncryptData:(NSData *)content {
SecKeyRef publicKey;
SecCertificateRef certificate;
SecPolicyRef policy;
SecTrustRef trust;
size_t maxPlainLen;
NSString *publicKeyPath = [[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"];
NSData *base64KeyData = [NSData dataWithContentsOfFile:publicKeyPath];
certificate = SecCertificateCreateWithData(kCFAllocatorDefault, ( __bridge CFDataRef) base64KeyData);
if (certificate == nil) {
NSLog(@"Can not read certificate from data");
return nil;
}
policy = SecPolicyCreateBasicX509();
OSStatus returnCode = SecTrustCreateWithCertificates(certificate, policy, &trust);
if (returnCode != 0) {
NSLog(@"SecTrustCreateWithCertificates fail. Error Code: %d", (int)returnCode);
return nil;
}
SecTrustResultType trustResultType;
returnCode = SecTrustEvaluate(trust, &trustResultType);
if (returnCode != 0) {
return nil;
}
publicKey = SecTrustCopyPublicKey(trust);
if (publicKey == nil) {
NSLog(@"SecTrustCopyPublicKey fail");
return nil;
}
maxPlainLen = SecKeyGetBlockSize(publicKey) - 12;
size_t plainLen = [content length];
if (plainLen > maxPlainLen) {
NSLog(@"content(%ld) is too long, must < %ld", plainLen, maxPlainLen);
return nil;
}
void *plain = malloc(plainLen);
[content getBytes:plain
length:plainLen];
size_t cipherLen = 128; // currently RSA key length is set to 128 bytes
void *cipher = malloc(cipherLen);
OSStatus encryptReturnCode = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, plain,
plainLen, cipher, &cipherLen);
NSData *result = nil;
if (encryptReturnCode != 0) {
NSLog(@"SecKeyEncrypt fail. Error Code: %d", (int)returnCode);
}
else {
result = [NSData dataWithBytes:cipher
length:cipherLen];
}
free(plain);
free(cipher);
return result;
}
Run Code Online (Sandbox Code Playgroud)
我一直在使用OpenSSL的尝试PEM_read_X509也PEM_read_RSAPrivateKey,但都无法读取的证书.我甚至都没有过去.如果我能在不依赖OpenSSL库的情况下做到这一点,那就更好了.
+(void)readTest{
FILE *fp;
X509 *x;
NSString *path =[[NSBundle mainBundle] pathForResource:@"private_key" ofType:@"pem"];
fp=fopen([path UTF8String],"r");
x=NULL;
PEM_read_X509(fp,&x,NULL,NULL); // I have also tried PEM_read_RSAPrivateKey
if (x == NULL) {
NSLog(@"Cant Read File"); // This ALWAYS fires
}
fclose(fp);
X509_free(x);
}
Run Code Online (Sandbox Code Playgroud)
如果有人可以帮助我使用X.509 RSA对加密/解密,我会很感激.谢谢.
您的私钥似乎是加密的(openssl要求您在命令行上输入密码),但是当您尝试打开它时,您不会解密它.此外,private_key.pem是RSA密钥,而不是证书,因此您应该使用PEM_read_RSAPrivateKey.
以下解码代码应该有效:
int pass_cb(char *buf, int size, int rwflag, void* password) {
snprintf(buf, size, "%s", (char*) password);
return strlen(buf);
}
+(void)readTest{
FILE *fp;
RSA *x;
NSString *path =[[NSBundle mainBundle] pathForResource:@"private_key" ofType:@"pem"];
fp=fopen([path UTF8String],"r");
x = PEM_read_RSAPrivateKey(fp,&x,pass_cb,"key password");
if (x == NULL) {
NSLog(@"Cant Read File"); // This ALWAYS fires
}
fclose(fp);
X509_free(x);
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以生成非加密密钥.-nodes创建密钥和证书时传递给openssl.
请注意,您可能需要确保OpenSSL已正确初始化:
SSL_library_init();
OpenSSL_add_all_algorithms();
Run Code Online (Sandbox Code Playgroud)
此外,OpenSSL会生成错误消息,可以帮助您完成开发.您加载错误字符串:
SSL_load_error_strings();
Run Code Online (Sandbox Code Playgroud)
你可以打电话给:
ERR_print_errors_fp(stderr);
Run Code Online (Sandbox Code Playgroud)
OpenSSL不是唯一的解决方案,因为iOS上的安全框架包含您需要的一切.我猜你转向OpenSSL,因为你不知道如何将私钥文件转换为SecKeyDecrypt的有效参数.
诀窍是生成PKCS#12文件并进行调用SecPKCS12Import.
您可以使用OpenSSL生成此文件:
openssl x509 -inform der -outform pem -in public_key.der -out public_key.pem
openssl pkcs12 -export -in public_key.pem -inkey private_key.pem -out private_key.p12
Run Code Online (Sandbox Code Playgroud)
这将要求您输出密码.此密码应传递给SecPKCS12Import("key password"下面).
NSString *privateKeyPath = [[NSBundle mainBundle] pathForResource:@"private_key" ofType:@"p12"];
NSData *pkcs12key = [NSData dataWithContentsOfFile:privateKeyPath];
NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys: @"key password", kSecImportExportPassphrase, nil];
CFArrayRef importedItems = NULL;
OSStatus returnCode = SecPKCS12Import(
(__bridge CFDataRef) pkcs12key,
(__bridge CFDictionaryRef) options,
&importedItems
);
Run Code Online (Sandbox Code Playgroud)
importedItems 是一个包含所有导入的PKCS12项的数组,基本上是"身份"(私钥+证书).
NSDictionary* item = (NSDictionary*) CFArrayGetValueAtIndex(importedItems, 0);
SecIdentityRef identity = (__bridge SecIdentityRef) [item objectForKey:(__bridge NSString *) kSecImportItemIdentity];
SecKeyRef privateKeyRef;
SecIdentityCopyPrivateKey(identity, &privateKeyRef);
Run Code Online (Sandbox Code Playgroud)
然后你可以使用privateKeyRef来执行解密SecKeyDecrypt.要匹配您的加密例程:
size_t cipherLen = [content length];
void *cipher = malloc(cipherLen);
[content getBytes:cipher length:cipherLen];
size_t plainLen = SecKeyGetBlockSize(privateKeyRef) - 12;
void *plain = malloc(plainLen);
OSStatus decryptReturnCode = SecKeyDecrypt(privateKeyRef, kSecPaddingPKCS1, cipher, cipherLen, plain, &plainLen);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4602 次 |
| 最近记录: |