1.生成私钥文件
$ openssl genrsa -out private.pem 1024
openssl:是一个自由的软件组织,专注做加密和解密的框架。
genrsa:指定了生成了算法使用RSA
-out:后面的参数表示生成的key的输入文件
1024:表示的是生成key的长度,单位字节(bits)
2.创建证书请求(按照提示输入信息)接下来就是公司名字,省市,还有名字的一些信息按着给下填就行。
$ openssl req -new -key private_key.pem -out public_key.csr
3.可以拿着这个文件去数字证书颁发机构(即CA)申请一个数字证书。CA会给你一个新的文件cacert.pem,那才是你的数字证书。(要收费的)
生成证书并签名,有效期10年
$ openssl x509 -req -days 3650 -in public_key.csr -signkey private_key.pem -out public_key.crt
509是一种非常通用的证书格式。
4.将用上面生成的密钥private_key.pem和public_key.csr证书请求文件生成一个数字证书public_key.crt。这个就是公钥
转换格式 将 PEM 格式文件 转换成 DER 格式
$ openssl x509 -outform der -in public_key.crt -out public_key.der
5.在 iOS开发中,公钥是不能使用base64编码的,上面的命令是将公钥的base64编码字符串转换成二进制数据
导出 P12 文件
在iOS使用私钥不能直接使用,需要导出一个p12文件。下面命令就是将私钥文件导出为p12文件。
$ openssl pkcs12 -export -out pkcs.p12 -inkey private_key.pem -in public_key.crt
(iOS中验证证书。把public_key.der拖到xcode中,如果文件没有问题的话,那么就可以直接在xcode中打开,看到证书的各种信息)
//后台需要
根据私钥生成公钥: openssl rsa -in private_key.pem -out public_key.pem -pubout
在Java(后台)中这时候的私钥还不能直接被使用,需要进行PKCS#8编码:
openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt
$ openssl genrsa -out private.pem 1024
openssl:是一个自由的软件组织,专注做加密和解密的框架。
genrsa:指定了生成了算法使用RSA
-out:后面的参数表示生成的key的输入文件
1024:表示的是生成key的长度,单位字节(bits)
2.创建证书请求(按照提示输入信息)接下来就是公司名字,省市,还有名字的一些信息按着给下填就行。
$ openssl req -new -key private_key.pem -out public_key.csr
3.可以拿着这个文件去数字证书颁发机构(即CA)申请一个数字证书。CA会给你一个新的文件cacert.pem,那才是你的数字证书。(要收费的)
生成证书并签名,有效期10年
$ openssl x509 -req -days 3650 -in public_key.csr -signkey private_key.pem -out public_key.crt
509是一种非常通用的证书格式。
4.将用上面生成的密钥private_key.pem和public_key.csr证书请求文件生成一个数字证书public_key.crt。这个就是公钥
转换格式 将 PEM 格式文件 转换成 DER 格式
$ openssl x509 -outform der -in public_key.crt -out public_key.der
5.在 iOS开发中,公钥是不能使用base64编码的,上面的命令是将公钥的base64编码字符串转换成二进制数据
导出 P12 文件
在iOS使用私钥不能直接使用,需要导出一个p12文件。下面命令就是将私钥文件导出为p12文件。
$ openssl pkcs12 -export -out pkcs.p12 -inkey private_key.pem -in public_key.crt
(iOS中验证证书。把public_key.der拖到xcode中,如果文件没有问题的话,那么就可以直接在xcode中打开,看到证书的各种信息)
//后台需要
根据私钥生成公钥: openssl rsa -in private_key.pem -out public_key.pem -pubout
在Java(后台)中这时候的私钥还不能直接被使用,需要进行PKCS#8编码:
openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt
用法示例:
#import"RSA.h"
//创建加密对象
RSA *rsa = [[RSA alloc]init];
//要加密的内容
NSString *msg = @"i love you";
//加载公钥
NSString *publicPath = [[NSBundle mainBundle] pathForResource:@"public_key.der" ofType:nil];
[rsa extractPublicKeyFromCertificateFilePublicKeyPath:publicPath];
//使用公钥加密
NSString *result = [rsa encryptToString:msg];
NSLog(@"加密 = %@",result);
//解密
//加载私钥
//密码是导出p12密码
NSString *privatePath = [[NSBundle mainBundle] pathForResource:@"pkcs" ofType:@"p12"];
[rsa extractEveryThingFromPKCS12FilePkcsPath:privatePath passphrase:@"123456"];
//使用私钥解密
NSString *result2 = [rsa decryptToString:result];
RSA *rsa = [[RSA alloc]init];
//要加密的内容
NSString *msg = @"i love you";
//加载公钥
NSString *publicPath = [[NSBundle mainBundle] pathForResource:@"public_key.der" ofType:nil];
[rsa extractPublicKeyFromCertificateFilePublicKeyPath:publicPath];
//使用公钥加密
NSString *result = [rsa encryptToString:msg];
NSLog(@"加密 = %@",result);
//解密
//加载私钥
//密码是导出p12密码
NSString *privatePath = [[NSBundle mainBundle] pathForResource:@"pkcs" ofType:@"p12"];
[rsa extractEveryThingFromPKCS12FilePkcsPath:privatePath passphrase:@"123456"];
//使用私钥解密
NSString *result2 = [rsa decryptToString:result];
NSLog(@"解密 = %@",result2);
RSA======Demo
**********************************RSA.h********************************************************************//
//
// RSA.h
// ICFundManager
//
// Created by magus on 15/12/21.
// Copyright © 2015年 基金组. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface RSA : NSObject {
SecKeyRef _publicKey;
SecKeyRef _privateKey;
SecCertificateRef certificate;
SecPolicyRef policy;
SecTrustRef trust;
size_t maxPlainLen;
}
//证书获取公钥
- (OSStatus)extractPublicKeyFromCertificateFilePublicKeyPath:(NSString *)publicKeyPath;
//数据加密
- (NSMutableData *)encryptWithPublicKey:(NSData *)plainData;
- (NSData *) encryptWithString:(NSString *)content;
- (NSString *) encryptToString:(NSString *)content;
// 获取私钥。--解密
//从p12文件中获取私钥 ,密码是你生成私钥的时候生成的
- (OSStatus)extractEveryThingFromPKCS12FilePkcsPath:(NSString *)pkcsPath passphrase:(NSString *)pkcsPassword;
//数据解密。
- (NSData *)decryptWithPrivateKey:(NSData *)cipherData;
- (NSString *)decryptToString:(NSString *)content;
- (NSData *)decryptWithString:(NSString *)content;
//
// Created by magus on 15/12/21.
// Copyright © 2015年 基金组. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface RSA : NSObject {
SecKeyRef _publicKey;
SecKeyRef _privateKey;
SecCertificateRef certificate;
SecPolicyRef policy;
SecTrustRef trust;
size_t maxPlainLen;
}
//证书获取公钥
- (OSStatus)extractPublicKeyFromCertificateFilePublicKeyPath:(NSString *)publicKeyPath;
//数据加密
- (NSMutableData *)encryptWithPublicKey:(NSData *)plainData;
- (NSData *) encryptWithString:(NSString *)content;
- (NSString *) encryptToString:(NSString *)content;
// 获取私钥。--解密
//从p12文件中获取私钥 ,密码是你生成私钥的时候生成的
- (OSStatus)extractEveryThingFromPKCS12FilePkcsPath:(NSString *)pkcsPath passphrase:(NSString *)pkcsPassword;
//数据解密。
- (NSData *)decryptWithPrivateKey:(NSData *)cipherData;
- (NSString *)decryptToString:(NSString *)content;
- (NSData *)decryptWithString:(NSString *)content;
@end
**********************************RSA.m********************************************************************//
//
// RSA—.m
// ICFundManager
//
// Created by magus on 15/12/21.
// Copyright © 2015年 基金组. All rights reserved.
//
#import "RSA.h"
@implementation RSA
/*
http://blog.csdn.net/chaijunkun/article/details/7275632
IOS中RSA的加密解密
1.生成私钥文件
$ openssl genrsa -out private.pem 1024
openssl:是一个自由的软件组织,专注做加密和解密的框架。
genrsa:指定了生成了算法使用RSA
-out:后面的参数表示生成的key的输入文件
1024:表示的是生成key的长度,单位字节(bits)
2.创建证书请求(按照提示输入信息)接下来就是公司名字,省市,还有名字的一些信息按着给下填就行。
$ openssl req -new -key private_key.pem -out public_key.csr
3.可以拿着这个文件去数字证书颁发机构(即CA)申请一个数字证书。CA会给你一个新的文件cacert.pem,那才是你的数字证书。(要收费的)
生成证书并签名,有效期10年
$ openssl x509 -req -days 3650 -in public_key.csr -signkey private_key.pem -out public_key.crt
509是一种非常通用的证书格式。
4.将用上面生成的密钥private_key.pem和public_key.csr证书请求文件生成一个数字证书public_key.crt。这个就是公钥
转换格式 将 PEM 格式文件 转换成 DER 格式
$ openssl x509 -outform der -in public_key.crt -out public_key.der
5.在 iOS开发中,公钥是不能使用base64编码的,上面的命令是将公钥的base64编码字符串转换成二进制数据
导出 P12 文件
在iOS使用私钥不能直接使用,需要导出一个p12文件。下面命令就是将私钥文件导出为p12文件。
$ openssl pkcs12 -export -out pkcs.p12 -inkey private_key.pem -in public_key.crt
(iOS中验证证书。把public_key.der拖到xcode中,如果文件没有问题的话,那么就可以直接在xcode中打开,看到证书的各种信息)
//后台需要
根据私钥生成公钥: openssl rsa -in private_key.pem -out public_key.pem -pubout
在Java(后台)中这时候的私钥还不能直接被使用,需要进行PKCS#8编码:
openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt
*/
- (id)init{
if (self = [super init]) {
}
return self;
}
//4 证书获取公钥
- (OSStatus)extractPublicKeyFromCertificateFilePublicKeyPath:(NSString *)publicKeyPath {
OSStatus status = -1;
if (_publicKey == nil) {
SecTrustResultType trustResult;
NSData *derData = [NSData dataWithContentsOfFile:publicKeyPath];
if (derData) {
SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)derData);
policy = SecPolicyCreateBasicX509();
status = SecTrustCreateWithCertificates(cert, policy, &trust);
if (status == errSecSuccess && trust) {
NSArray *certs = [NSArray arrayWithObject:(id)cert];
status = SecTrustSetAnchorCertificates(trust, (CFArrayRef)certs);
if (status == errSecSuccess) {
status = SecTrustEvaluate(trust, &trustResult);
// 自签名证书可信
if (status == errSecSuccess && (trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed)) {
_publicKey = SecTrustCopyPublicKey(trust);
if (_publicKey) {
NSLog(@"Get public key successfully~ %@", _publicKey);
}
if (cert) {
CFRelease(cert);
}
if (policy) {
CFRelease(policy);
}
if (trust) {
CFRelease(trust);
}
}
}
}
}
}
return status;
}
//5. 用公钥对数据加密。
//加密
- (NSMutableData *)encryptWithPublicKey:(NSData *)plainData {
// 分配内存块,用于存放加密后的数据段
size_t cipherBufferSize = SecKeyGetBlockSize(_publicKey);
uint8_t *cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
double totalLength = [plainData length];
size_t blockSize = cipherBufferSize - 12;
size_t blockCount = (size_t)ceil(totalLength / blockSize);
NSMutableData *encryptedData = [NSMutableData data];
// 分段加密
for (int i = 0; i < blockCount; i++) {
NSUInteger loc = i * blockSize;
// 数据段的实际大小。最后一段可能比blockSize小。
int dataSegmentRealSize = (int)MIN(blockSize, [plainData length] - loc);
// 截取需要加密的数据段
NSData *dataSegment = [plainData subdataWithRange:NSMakeRange(loc, dataSegmentRealSize)];
OSStatus status = SecKeyEncrypt(_publicKey, kSecPaddingPKCS1, (const uint8_t *)[dataSegment bytes], dataSegmentRealSize, cipherBuffer, &cipherBufferSize);
if (status == errSecSuccess) {
NSData *encryptedDataSegment = [[NSData alloc] initWithBytes:(const void *)cipherBuffer length:cipherBufferSize];
// 追加加密后的数据段
[encryptedData appendData:encryptedDataSegment];
[encryptedDataSegment release];
} else {
if (cipherBuffer) {
free(cipherBuffer);
}
return nil;
}
}
if (cipherBuffer) {
free(cipherBuffer);
}
return encryptedData;
}
//加密
- (NSData *) encryptWithString:(NSString *)content
{
if (content == nil || !content) {
return nil;
}
return [self encryptWithPublicKey:[content dataUsingEncoding:NSUTF8StringEncoding]];
}
- (NSString *) encryptToString:(NSString *)content
{
NSData *data = [self encryptWithString:content];
//base64编码
// NSString *base64Encoded = [data base64EncodedStringWithOptions:0];
// return base64Encoded;
return [self base64forData:data];
}
//6. 获取私钥。
//从p12文件中获取私钥 ,密码是你生成私钥的时候生成的
- (OSStatus)extractEveryThingFromPKCS12FilePkcsPath:(NSString *)pkcsPath passphrase:(NSString *)pkcsPassword{
SecIdentityRef identity;
OSStatus status = -1;
if (_privateKey == nil) {
NSData *p12Data = [NSData dataWithContentsOfFile:pkcsPath];
if (p12Data) {
CFStringRef password = (CFStringRef)pkcsPassword;
const void *keys[] = {
kSecImportExportPassphrase
};
const void *values[] = {
password
};
CFDictionaryRef options = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(kCFAllocatorDefault, NULL, 0, NULL);
status = SecPKCS12Import((CFDataRef)p12Data, options, &items);
if (status == errSecSuccess) {
CFDictionaryRef identity_trust_dic = CFArrayGetValueAtIndex(items, 0);
identity = (SecIdentityRef)CFDictionaryGetValue(identity_trust_dic, kSecImportItemIdentity);
trust = (SecTrustRef)CFDictionaryGetValue(identity_trust_dic, kSecImportItemTrust);
// certs数组中包含了所有的证书
CFArrayRef certs = (CFArrayRef)CFDictionaryGetValue(identity_trust_dic, kSecImportItemCertChain);
if ([(NSArray *)certs count] && trust && identity) {
// 如果没有下面一句,自签名证书的评估信任结果永远是kSecTrustResultRecoverableTrustFailure
status = SecTrustSetAnchorCertificates(trust, certs);
if (status == errSecSuccess) {
SecTrustResultType trustResultType;
// 通常, 返回的trust result type应为kSecTrustResultUnspecified,如果是,就可以说明签名证书是可信的
status = SecTrustEvaluate(trust, &trustResultType);
if ((trustResultType == kSecTrustResultUnspecified || trustResultType == kSecTrustResultProceed) && status == errSecSuccess) {
// 证书可信,可以提取私钥与公钥,然后可以使用公私钥进行加解密操作
status = SecIdentityCopyPrivateKey(identity, &_privateKey);
if (status == errSecSuccess && _privateKey) {
// 成功提取私钥
NSLog(@"Get private key successfully~ %@", _privateKey);
}
}
}
}
}
if (options) {
CFRelease(options);
}
}
}
return 0;
}
//7.数据解密。
- (NSData *)decryptWithPrivateKey:(NSData *)cipherData {
// 分配内存块,用于存放解密后的数据段
size_t plainBufferSize = SecKeyGetBlockSize(_privateKey);
NSLog(@"plainBufferSize = %zd", plainBufferSize);
uint8_t *plainBuffer = malloc(plainBufferSize * sizeof(uint8_t));
// 计算数据段最大长度及数据段的个数
NSLog(@"totalLength = %lu", (unsigned long)[cipherData length]);
int totalLength = (int) [cipherData length];
NSLog(@"totalLength = %d", totalLength);
size_t blockSize = plainBufferSize;
size_t blockCount = (size_t)ceil(totalLength / blockSize);
NSMutableData *decryptedData = [NSMutableData data];
// 分段解密
for (int i = 0; i < blockCount; i++) {
NSUInteger loc = i * blockSize;
// 数据段的实际大小。最后一段可能比blockSize小。
int dataSegmentRealSize =(int) MIN(blockSize, totalLength - loc);
// 截取需要解密的数据段
NSData *dataSegment = [cipherData subdataWithRange:NSMakeRange(loc, dataSegmentRealSize)];
OSStatus status = SecKeyDecrypt(_privateKey, kSecPaddingPKCS1, (const uint8_t *)[dataSegment bytes], dataSegmentRealSize, plainBuffer, &plainBufferSize);
if (status == errSecSuccess) {
NSData *decryptedDataSegment = [[NSData alloc] initWithBytes:(const void *)plainBuffer length:plainBufferSize];
[decryptedData appendData:decryptedDataSegment];
[decryptedDataSegment release];
} else {
if (plainBuffer) {
free(plainBuffer);
}
return nil;
}
}
if (plainBuffer) {
free(plainBuffer);
}
return decryptedData;
}
- (NSData *)decryptWithString:(NSString *)content
{
NSLog(@"conten = %@",content);
if (content == nil || !content) {
return nil;
}
//base64解码
NSData *dataFromBase64String = [[NSData alloc] initWithBase64EncodedString:content options:0];
return [self decryptWithPrivateKey:dataFromBase64String];
}
- (NSString *)decryptToString:(NSString *)content {
NSData *decryptData = [self decryptWithString:content];
//NSData -->NSString
NSString *decryptStr = [[NSString alloc] initWithData:decryptData encoding:NSUTF8StringEncoding];
return decryptStr;
}
// convert NSData to NSString
- (NSString *)base64forData:(NSData *)theData {
const uint8_t* input = (const uint8_t*)[theData bytes];
NSInteger length = [theData length];
static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t* output = (uint8_t*)data.mutableBytes;
NSInteger i;
for (i=0; i < length; i += 3) {
NSInteger value = 0;
NSInteger j;
for (j = i; j < (i + 3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
NSInteger theIndex = (i / 3) * 4;
output[theIndex + 0] = table[(value >> 18) & 0x3F];
output[theIndex + 1] = table[(value >> 12) & 0x3F];
output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '=';
output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '=';
}
return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
}
/*
NSString *content = @"nihao";
//系统自带的 NS_AVAILABLE(10_9, 7_0);//base64编码
//NSString -->NSData
NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
//NSData--base64编码-->NSString
NSString *base64Encoded = [data base64EncodedStringWithOptions:0];
//base64解码
NSString(base64编码) --base64解码-->NSData
NSData *data1 = [[NSData alloc] initWithBase64EncodedString:content options:0];
//NSData--->NSString
NSString *deStr = [[NSString alloc] initWithData:data1 encoding:NSUTF8StringEncoding];
*/
/*
用法示例:
//创建加密对象
RSA *rsa = [[RSA alloc]init];
//要加密的内容
NSString *msg = @"i love you";
//加载公钥
NSString *publicPath = [[NSBundle mainBundle] pathForResource:@"public_key.der" ofType:nil];
[rsa extractPublicKeyFromCertificateFilePublicKeyPath:publicPath];
//使用公钥加密
NSString *result = [rsa encryptToString:msg];
NSLog(@"加密 = %@",result);
//解密
//加载私钥
//密码是导出p12密码
NSString *privatePath = [[NSBundle mainBundle] pathForResource:@"pkcs" ofType:@"p12"];
[rsa extractEveryThingFromPKCS12FilePkcsPath:privatePath passphrase:@"123456"];
//使用私钥解密
NSString *result2 = [rsa decryptToString:result];
NSLog(@"解密 = %@",result2);
*/
@end
// RSA—.m
// ICFundManager
//
// Created by magus on 15/12/21.
// Copyright © 2015年 基金组. All rights reserved.
//
#import "RSA.h"
@implementation RSA
/*
http://blog.csdn.net/chaijunkun/article/details/7275632
IOS中RSA的加密解密
1.生成私钥文件
$ openssl genrsa -out private.pem 1024
openssl:是一个自由的软件组织,专注做加密和解密的框架。
genrsa:指定了生成了算法使用RSA
-out:后面的参数表示生成的key的输入文件
1024:表示的是生成key的长度,单位字节(bits)
2.创建证书请求(按照提示输入信息)接下来就是公司名字,省市,还有名字的一些信息按着给下填就行。
$ openssl req -new -key private_key.pem -out public_key.csr
3.可以拿着这个文件去数字证书颁发机构(即CA)申请一个数字证书。CA会给你一个新的文件cacert.pem,那才是你的数字证书。(要收费的)
生成证书并签名,有效期10年
$ openssl x509 -req -days 3650 -in public_key.csr -signkey private_key.pem -out public_key.crt
509是一种非常通用的证书格式。
4.将用上面生成的密钥private_key.pem和public_key.csr证书请求文件生成一个数字证书public_key.crt。这个就是公钥
转换格式 将 PEM 格式文件 转换成 DER 格式
$ openssl x509 -outform der -in public_key.crt -out public_key.der
5.在 iOS开发中,公钥是不能使用base64编码的,上面的命令是将公钥的base64编码字符串转换成二进制数据
导出 P12 文件
在iOS使用私钥不能直接使用,需要导出一个p12文件。下面命令就是将私钥文件导出为p12文件。
$ openssl pkcs12 -export -out pkcs.p12 -inkey private_key.pem -in public_key.crt
(iOS中验证证书。把public_key.der拖到xcode中,如果文件没有问题的话,那么就可以直接在xcode中打开,看到证书的各种信息)
//后台需要
根据私钥生成公钥: openssl rsa -in private_key.pem -out public_key.pem -pubout
在Java(后台)中这时候的私钥还不能直接被使用,需要进行PKCS#8编码:
openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt
*/
- (id)init{
if (self = [super init]) {
}
return self;
}
//4 证书获取公钥
- (OSStatus)extractPublicKeyFromCertificateFilePublicKeyPath:(NSString *)publicKeyPath {
OSStatus status = -1;
if (_publicKey == nil) {
SecTrustResultType trustResult;
NSData *derData = [NSData dataWithContentsOfFile:publicKeyPath];
if (derData) {
SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)derData);
policy = SecPolicyCreateBasicX509();
status = SecTrustCreateWithCertificates(cert, policy, &trust);
if (status == errSecSuccess && trust) {
NSArray *certs = [NSArray arrayWithObject:(id)cert];
status = SecTrustSetAnchorCertificates(trust, (CFArrayRef)certs);
if (status == errSecSuccess) {
status = SecTrustEvaluate(trust, &trustResult);
// 自签名证书可信
if (status == errSecSuccess && (trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed)) {
_publicKey = SecTrustCopyPublicKey(trust);
if (_publicKey) {
NSLog(@"Get public key successfully~ %@", _publicKey);
}
if (cert) {
CFRelease(cert);
}
if (policy) {
CFRelease(policy);
}
if (trust) {
CFRelease(trust);
}
}
}
}
}
}
return status;
}
//5. 用公钥对数据加密。
//加密
- (NSMutableData *)encryptWithPublicKey:(NSData *)plainData {
// 分配内存块,用于存放加密后的数据段
size_t cipherBufferSize = SecKeyGetBlockSize(_publicKey);
uint8_t *cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
double totalLength = [plainData length];
size_t blockSize = cipherBufferSize - 12;
size_t blockCount = (size_t)ceil(totalLength / blockSize);
NSMutableData *encryptedData = [NSMutableData data];
// 分段加密
for (int i = 0; i < blockCount; i++) {
NSUInteger loc = i * blockSize;
// 数据段的实际大小。最后一段可能比blockSize小。
int dataSegmentRealSize = (int)MIN(blockSize, [plainData length] - loc);
// 截取需要加密的数据段
NSData *dataSegment = [plainData subdataWithRange:NSMakeRange(loc, dataSegmentRealSize)];
OSStatus status = SecKeyEncrypt(_publicKey, kSecPaddingPKCS1, (const uint8_t *)[dataSegment bytes], dataSegmentRealSize, cipherBuffer, &cipherBufferSize);
if (status == errSecSuccess) {
NSData *encryptedDataSegment = [[NSData alloc] initWithBytes:(const void *)cipherBuffer length:cipherBufferSize];
// 追加加密后的数据段
[encryptedData appendData:encryptedDataSegment];
[encryptedDataSegment release];
} else {
if (cipherBuffer) {
free(cipherBuffer);
}
return nil;
}
}
if (cipherBuffer) {
free(cipherBuffer);
}
return encryptedData;
}
//加密
- (NSData *) encryptWithString:(NSString *)content
{
if (content == nil || !content) {
return nil;
}
return [self encryptWithPublicKey:[content dataUsingEncoding:NSUTF8StringEncoding]];
}
- (NSString *) encryptToString:(NSString *)content
{
NSData *data = [self encryptWithString:content];
//base64编码
// NSString *base64Encoded = [data base64EncodedStringWithOptions:0];
// return base64Encoded;
return [self base64forData:data];
}
//6. 获取私钥。
//从p12文件中获取私钥 ,密码是你生成私钥的时候生成的
- (OSStatus)extractEveryThingFromPKCS12FilePkcsPath:(NSString *)pkcsPath passphrase:(NSString *)pkcsPassword{
SecIdentityRef identity;
OSStatus status = -1;
if (_privateKey == nil) {
NSData *p12Data = [NSData dataWithContentsOfFile:pkcsPath];
if (p12Data) {
CFStringRef password = (CFStringRef)pkcsPassword;
const void *keys[] = {
kSecImportExportPassphrase
};
const void *values[] = {
password
};
CFDictionaryRef options = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(kCFAllocatorDefault, NULL, 0, NULL);
status = SecPKCS12Import((CFDataRef)p12Data, options, &items);
if (status == errSecSuccess) {
CFDictionaryRef identity_trust_dic = CFArrayGetValueAtIndex(items, 0);
identity = (SecIdentityRef)CFDictionaryGetValue(identity_trust_dic, kSecImportItemIdentity);
trust = (SecTrustRef)CFDictionaryGetValue(identity_trust_dic, kSecImportItemTrust);
// certs数组中包含了所有的证书
CFArrayRef certs = (CFArrayRef)CFDictionaryGetValue(identity_trust_dic, kSecImportItemCertChain);
if ([(NSArray *)certs count] && trust && identity) {
// 如果没有下面一句,自签名证书的评估信任结果永远是kSecTrustResultRecoverableTrustFailure
status = SecTrustSetAnchorCertificates(trust, certs);
if (status == errSecSuccess) {
SecTrustResultType trustResultType;
// 通常, 返回的trust result type应为kSecTrustResultUnspecified,如果是,就可以说明签名证书是可信的
status = SecTrustEvaluate(trust, &trustResultType);
if ((trustResultType == kSecTrustResultUnspecified || trustResultType == kSecTrustResultProceed) && status == errSecSuccess) {
// 证书可信,可以提取私钥与公钥,然后可以使用公私钥进行加解密操作
status = SecIdentityCopyPrivateKey(identity, &_privateKey);
if (status == errSecSuccess && _privateKey) {
// 成功提取私钥
NSLog(@"Get private key successfully~ %@", _privateKey);
}
}
}
}
}
if (options) {
CFRelease(options);
}
}
}
return 0;
}
//7.数据解密。
- (NSData *)decryptWithPrivateKey:(NSData *)cipherData {
// 分配内存块,用于存放解密后的数据段
size_t plainBufferSize = SecKeyGetBlockSize(_privateKey);
NSLog(@"plainBufferSize = %zd", plainBufferSize);
uint8_t *plainBuffer = malloc(plainBufferSize * sizeof(uint8_t));
// 计算数据段最大长度及数据段的个数
NSLog(@"totalLength = %lu", (unsigned long)[cipherData length]);
int totalLength = (int) [cipherData length];
NSLog(@"totalLength = %d", totalLength);
size_t blockSize = plainBufferSize;
size_t blockCount = (size_t)ceil(totalLength / blockSize);
NSMutableData *decryptedData = [NSMutableData data];
// 分段解密
for (int i = 0; i < blockCount; i++) {
NSUInteger loc = i * blockSize;
// 数据段的实际大小。最后一段可能比blockSize小。
int dataSegmentRealSize =(int) MIN(blockSize, totalLength - loc);
// 截取需要解密的数据段
NSData *dataSegment = [cipherData subdataWithRange:NSMakeRange(loc, dataSegmentRealSize)];
OSStatus status = SecKeyDecrypt(_privateKey, kSecPaddingPKCS1, (const uint8_t *)[dataSegment bytes], dataSegmentRealSize, plainBuffer, &plainBufferSize);
if (status == errSecSuccess) {
NSData *decryptedDataSegment = [[NSData alloc] initWithBytes:(const void *)plainBuffer length:plainBufferSize];
[decryptedData appendData:decryptedDataSegment];
[decryptedDataSegment release];
} else {
if (plainBuffer) {
free(plainBuffer);
}
return nil;
}
}
if (plainBuffer) {
free(plainBuffer);
}
return decryptedData;
}
- (NSData *)decryptWithString:(NSString *)content
{
NSLog(@"conten = %@",content);
if (content == nil || !content) {
return nil;
}
//base64解码
NSData *dataFromBase64String = [[NSData alloc] initWithBase64EncodedString:content options:0];
return [self decryptWithPrivateKey:dataFromBase64String];
}
- (NSString *)decryptToString:(NSString *)content {
NSData *decryptData = [self decryptWithString:content];
//NSData -->NSString
NSString *decryptStr = [[NSString alloc] initWithData:decryptData encoding:NSUTF8StringEncoding];
return decryptStr;
}
// convert NSData to NSString
- (NSString *)base64forData:(NSData *)theData {
const uint8_t* input = (const uint8_t*)[theData bytes];
NSInteger length = [theData length];
static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t* output = (uint8_t*)data.mutableBytes;
NSInteger i;
for (i=0; i < length; i += 3) {
NSInteger value = 0;
NSInteger j;
for (j = i; j < (i + 3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
NSInteger theIndex = (i / 3) * 4;
output[theIndex + 0] = table[(value >> 18) & 0x3F];
output[theIndex + 1] = table[(value >> 12) & 0x3F];
output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '=';
output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '=';
}
return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
}
/*
NSString *content = @"nihao";
//系统自带的 NS_AVAILABLE(10_9, 7_0);//base64编码
//NSString -->NSData
NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
//NSData--base64编码-->NSString
NSString *base64Encoded = [data base64EncodedStringWithOptions:0];
//base64解码
NSString(base64编码) --base64解码-->NSData
NSData *data1 = [[NSData alloc] initWithBase64EncodedString:content options:0];
//NSData--->NSString
NSString *deStr = [[NSString alloc] initWithData:data1 encoding:NSUTF8StringEncoding];
*/
/*
用法示例:
//创建加密对象
RSA *rsa = [[RSA alloc]init];
//要加密的内容
NSString *msg = @"i love you";
//加载公钥
NSString *publicPath = [[NSBundle mainBundle] pathForResource:@"public_key.der" ofType:nil];
[rsa extractPublicKeyFromCertificateFilePublicKeyPath:publicPath];
//使用公钥加密
NSString *result = [rsa encryptToString:msg];
NSLog(@"加密 = %@",result);
//解密
//加载私钥
//密码是导出p12密码
NSString *privatePath = [[NSBundle mainBundle] pathForResource:@"pkcs" ofType:@"p12"];
[rsa extractEveryThingFromPKCS12FilePkcsPath:privatePath passphrase:@"123456"];
//使用私钥解密
NSString *result2 = [rsa decryptToString:result];
NSLog(@"解密 = %@",result2);
*/
@end