最近項(xiàng)目中為了數(shù)據(jù)安全運(yùn)用到了RSA非對(duì)稱加密,所以抽空把它記錄下來拷况。前期在網(wǎng)上找了很多代碼惯驼,很多都寫得挺不錯(cuò)的。例如:前期的準(zhǔn)備工作和公鑰加密私鑰解密可以參考這篇文章匕荸,http://www.reibang.com/p/74a796ec5038爹谭。但是實(shí)際的開發(fā)過程中后臺(tái)只提供一個(gè)公鑰給客戶端,加密解密都是運(yùn)用此密鑰榛搔。接下來就為大家展示比較簡(jiǎn)單的實(shí)現(xiàn)方案诺凡。
步驟一:
下載加密文件 https://pan.baidu.com/s/1slsKG7F ,提取碼:hhbh践惑。下載完成后把文件整體放入工程中腹泌。其中包括兩個(gè).a文件和openssl文件(注意:在其他地方下載的文件要記得將存放.a文件 的文件夾和openssl文件夾放在同級(jí)目錄下,不然會(huì)報(bào)錯(cuò))尔觉,為了可以找到<openssl/asn1.h>(后面需要導(dǎo)入)需要在build settings --> header search paths 添加相應(yīng)的openssl的路徑,到include這層就ok了凉袱。如下圖:
步驟二:
找后臺(tái)要公鑰,一個(gè).pem的文件,如果沒有重命名一般叫做rsa_public_key.pem文件专甩。
步驟三:
創(chuàng)建RSAEncryptor類钟鸵,可將下面代碼直接復(fù)制粘貼入工程。
RSAEncryptor.h 文件代碼
/**
* 服務(wù)器公鑰加密方法
*
* @param str 需要加密的字符串
* @param path '.pem'格式的公鑰文件路徑
*/
+ (NSString *)pemEncryptString:(NSString *)str publicKeyWithContentsOfFile:(NSString *)path;
/**
* 服務(wù)器公鑰解密方法
*
* @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;
}
//服務(wù)器公鑰加密
+ (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;
}
//服務(wù)器公鑰解密
+ (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中調(diào)用方法涤躲。調(diào)用打印結(jié)果棺耍,如下圖: