最近项目中为了数据安全运用到了RSA非对称加密,所以抽空把它记录下来。前期在网上找了很多代码,很多都写得挺不错的。例如:前期的准备工作和公钥加密私钥解密可以参考这篇文章,http://www.jianshu.com/p/74a796ec5038。但是实际的开发过程中后台只提供一个公钥给客户端,加密解密都是运用此密钥。接下来就为大家展示比较简单的实现方案。
步骤一:
下载加密文件 https://pan.baidu.com/s/1slsKG7F ,提取码:hhbh。下载完成后把文件整体放入工程中。其中包括两个.a文件和openssl文件(注意:在其他地方下载的文件要记得将存放.a文件 的文件夹和openssl文件夹放在同级目录下,不然会报错),为了可以找到<openssl/asn1.h>(后面需要导入)需要在build settings --> header search paths 添加相应的openssl的路径,到include这层就ok了。如下图:
步骤二:
找后台要公钥,一个.pem的文件,如果没有重命名一般叫做rsa_public_key.pem文件。
步骤三:
创建RSAEncryptor类,可将下面代码直接复制粘贴入工程。
RSAEncryptor.h 文件代码
/**
* 服务器公钥加密方法
*
* @param str 需要加密的字符串
* @param path '.pem'格式的公钥文件路径
*/
+ (NSString *)pemEncryptString:(NSString *)str publicKeyWithContentsOfFile:(NSString *)path;
/**
* 服务器公钥解密方法
*
* @param str 需要解密的字符串
* @param path '.pem'格式的公钥文件路径
*/
+ (NSString *)pemDecryptString:(NSString *)str publicKeyWithContentsOfFile:(NSString *)path;
RSAEncryptor.m 文件代码
#import "RSAEncryptor.h"
#import <Security/Security.h>
#include "openssl/rsa.h"
#include "openssl/pem.h"
@implementation RSAEncryptor
static NSString *base64_encode_data(NSData *data){
data = [data base64EncodedDataWithOptions:0];
NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return ret;
}
static NSData *base64_decode(NSString *str){
NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
return data;
}
//服务器公钥加密
+ (NSString *)pemEncryptString:(NSString *)str publicKeyWithContentsOfFile:(NSString *)path {
char output[1024];
bzero(output, sizeof(output));
if (!str) {
return nil;
}
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
//公钥文件
const char *pub_key = [path UTF8String];
// 打开公钥文件
FILE *pub_fp = fopen(pub_key,"r");
if(pub_fp == NULL) {
return nil;
}
// 从文件中读取公钥
RSA *rsa = PEM_read_RSA_PUBKEY(pub_fp, NULL, NULL, NULL);
if(rsa == NULL){
return nil;
}
// 用公钥解密
int state = RSA_size(rsa);
state = RSA_public_encrypt((int)[str length], (unsigned char*)[data bytes], (unsigned char*)output, rsa, RSA_PKCS1_PADDING);
if(state == -1) {
return nil;
}
fclose(pub_fp);
// 输出解密后的明文
NSString *result = base64_encode_data([NSData dataWithBytes:output length:state]);
return result;
}
//服务器公钥解密
+ (NSString *)pemDecryptString:(NSString *)str publicKeyWithContentsOfFile:(NSString *)path {
char output[1024];
bzero(output, sizeof(output));
if (!str) {
return nil;
}
NSData *data = base64_decode(str);
//公钥和私钥文件
const char *pub_key = [path UTF8String];
// 打开私钥文件
FILE *pub_fp = fopen(pub_key,"r");
if(pub_fp == NULL) {
return nil;
}
// 从文件中读取公钥
RSA *rsa = PEM_read_RSA_PUBKEY(pub_fp, NULL, NULL, NULL);
if(rsa == NULL){
return nil;
}
// 用公钥解密
int state = RSA_size(rsa);
state = RSA_public_decrypt(state, (unsigned char*)[data bytes], (unsigned char*)output, rsa, RSA_PKCS1_PADDING);
if(state == -1) {
return nil;
}
fclose(pub_fp);
// 输出解密后的明文
output[state] = 0;
NSString *result = [NSString stringWithUTF8String:output];
return result;
}
@end
步骤四:
在ViewController中调用方法。调用打印结果,如下图: