#import <Foundation/Foundation.h>

@interface RSAEncryptor : NSObject

/**

*  加密方法

*

*  @param str   需要加密的字符串

*  @param path  '.der'格式的公钥文件路径

*/

+ (NSString *)encryptString:(NSString *)str publicKeyWithContentsOfFile:(NSString *)path;

/**

*  解密方法

*

*  @param str       需要解密的字符串

*  @param path      '.p12'格式的私钥文件路径

*  @param password  私钥文件密码

*/

+ (NSString *)decryptString:(NSString *)str privateKeyWithContentsOfFile:(NSString *)path password:(NSString *)password;

/**

*  加密方法

*

*  @param str    需要加密的字符串

*  @param pubKey 公钥字符串

*/

+ (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey;

/**

*  解密方法

*

*  @param str     需要解密的字符串

*  @param privKey 私钥字符串

*/

+ (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey;

@end

//

//  RSAEncryptor.m

//  RepairCenter

//

//  Created by 王效金 on 16/7/18.

//  Copyright © 2016年 Neil. All rights reserved.

//

#import "RSAEncryptor.h"

#import <Security/Security.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;

}

#pragma mark - 使用'.der'公钥文件加密

//加密

+ (NSString *)encryptString:(NSString *)str publicKeyWithContentsOfFile:(NSString *)path{

if (!str || !path)  return nil;

return [self encryptString:str publicKeyRef:[self getPublicKeyRefWithContentsOfFile:path]];

}

//获取公钥

+ (SecKeyRef)getPublicKeyRefWithContentsOfFile:(NSString *)filePath{

NSData *certData = [NSData dataWithContentsOfFile:filePath];

if (!certData) {

return nil;

}

SecCertificateRef cert = SecCertificateCreateWithData(NULL, (CFDataRef)certData);

SecKeyRef key = NULL;

SecTrustRef trust = NULL;

SecPolicyRef policy = NULL;

if (cert != NULL) {

policy = SecPolicyCreateBasicX509();

if (policy) {

if (SecTrustCreateWithCertificates((CFTypeRef)cert, policy, &trust) == noErr) {

SecTrustResultType result;

if (SecTrustEvaluate(trust, &result) == noErr) {

key = SecTrustCopyPublicKey(trust);

}

}

}

}

if (policy) CFRelease(policy);

if (trust) CFRelease(trust);

if (cert) CFRelease(cert);

return key;

}

+ (NSString *)encryptString:(NSString *)str publicKeyRef:(SecKeyRef)publicKeyRef{

if(![str dataUsingEncoding:NSUTF8StringEncoding]){

return nil;

}

if(!publicKeyRef){

return nil;

}

NSData *data = [self encryptData:[str dataUsingEncoding:NSUTF8StringEncoding] withKeyRef:publicKeyRef];

NSString *ret = base64_encode_data(data);

return ret;

}

#pragma mark - 使用'.12'私钥文件解密

//解密

+ (NSString *)decryptString:(NSString *)str privateKeyWithContentsOfFile:(NSString *)path password:(NSString *)password{

if (!str || !path) return nil;

if (!password) password = @"";

return [self decryptString:str privateKeyRef:[self getPrivateKeyRefWithContentsOfFile:path password:password]];

}

//获取私钥

+ (SecKeyRef)getPrivateKeyRefWithContentsOfFile:(NSString *)filePath password:(NSString*)password{

NSData *p12Data = [NSData dataWithContentsOfFile:filePath];

if (!p12Data) {

return nil;

}

SecKeyRef privateKeyRef = NULL;

NSMutableDictionary * options = [[NSMutableDictionary alloc] init];

[options setObject: password 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);

return privateKeyRef;

}

+ (NSString *)decryptString:(NSString *)str privateKeyRef:(SecKeyRef)privKeyRef{

NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];

if (!privKeyRef) {

return nil;

}

data = [self decryptData:data withKeyRef:privKeyRef];

NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

return ret;

}

#pragma mark - 使用公钥字符串加密

/* START: Encryption with RSA public key */

//使用公钥字符串加密

+ (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey{

NSData *data = [self encryptData:[str dataUsingEncoding:NSUTF8StringEncoding] publicKey:pubKey];

NSString *ret = base64_encode_data(data);

return ret;

}

+ (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey{

if(!data || !pubKey){

return nil;

}

SecKeyRef keyRef = [self addPublicKey:pubKey];

if(!keyRef){

return nil;

}

return [self encryptData:data withKeyRef:keyRef];

}

+ (SecKeyRef)addPublicKey:(NSString *)key{

NSRange spos = [key rangeOfString:@"-----BEGIN PUBLIC KEY-----"];

NSRange epos = [key rangeOfString:@"-----END PUBLIC KEY-----"];

if(spos.location != NSNotFound && epos.location != NSNotFound){

NSUInteger s = spos.location + spos.length;

NSUInteger e = epos.location;

NSRange range = NSMakeRange(s, e-s);

key = [key substringWithRange:range];

}

key = [key stringByReplacingOccurrencesOfString:@"\r" withString:@""];

key = [key stringByReplacingOccurrencesOfString:@"\n" withString:@""];

key = [key stringByReplacingOccurrencesOfString:@"\t" withString:@""];

key = [key stringByReplacingOccurrencesOfString:@" "  withString:@""];

// This will be base64 encoded, decode it.

NSData *data = base64_decode(key);

data = [self stripPublicKeyHeader:data];

if(!data){

return nil;

}

//a tag to read/write keychain storage

NSString *tag = @"RSAUtil_PubKey";

NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]];

// Delete any old lingering key with the same tag

NSMutableDictionary *publicKey = [[NSMutableDictionary alloc] init];

[publicKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass];

[publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];

[publicKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag];

SecItemDelete((__bridge CFDictionaryRef)publicKey);

// Add persistent version of the key to system keychain

[publicKey setObject:data forKey:(__bridge id)kSecValueData];

[publicKey setObject:(__bridge id) kSecAttrKeyClassPublic forKey:(__bridge id)

kSecAttrKeyClass];

[publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)

kSecReturnPersistentRef];

CFTypeRef persistKey = nil;

OSStatus status = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey);

if (persistKey != nil){

CFRelease(persistKey);

}

if ((status != noErr) && (status != errSecDuplicateItem)) {

return nil;

}

[publicKey removeObjectForKey:(__bridge id)kSecValueData];

[publicKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];

[publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];

[publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];

// Now fetch the SecKeyRef version of the key

SecKeyRef keyRef = nil;

status = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey, (CFTypeRef *)&keyRef);

if(status != noErr){

return nil;

}

return keyRef;

}

+ (NSData *)stripPublicKeyHeader:(NSData *)d_key{

// Skip ASN.1 public key header

if (d_key == nil) return(nil);

unsigned long len = [d_key length];

if (!len) return(nil);

unsigned char *c_key = (unsigned char *)[d_key bytes];

unsigned int  idx     = 0;

if (c_key[idx++] != 0x30) return(nil);

if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;

else idx++;

// PKCS #1 rsaEncryption szOID_RSA_RSA

static unsigned char seqiod[] =

{ 0x30,   0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,

0x01, 0x05, 0x00 };

if (memcmp(&c_key[idx], seqiod, 15)) return(nil);

idx += 15;

if (c_key[idx++] != 0x03) return(nil);

if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;

else idx++;

if (c_key[idx++] != '\0') return(nil);

// Now make a new NSData from this buffer

return ([NSData dataWithBytes:&c_key[idx] length:len - idx]);

}

+ (NSData *)encryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{

const uint8_t *srcbuf = (const uint8_t *)[data bytes];

size_t srclen = (size_t)data.length;

size_t block_size = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t);

void *outbuf = malloc(block_size);

size_t src_block_size = block_size - 11;

NSMutableData *ret = [[NSMutableData alloc] init];

for(int idx=0; idx<srclen; idx+=src_block_size){

//NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);

size_t data_len = srclen - idx;

if(data_len > src_block_size){

data_len = src_block_size;

}

size_t outlen = block_size;

OSStatus status = noErr;

status = SecKeyEncrypt(keyRef,

kSecPaddingPKCS1,

srcbuf + idx,

data_len,

outbuf,

&outlen

);

if (status != 0) {

NSLog(@"SecKeyEncrypt fail. Error Code: %d", (int)status);

ret = nil;

break;

}else{

[ret appendBytes:outbuf length:outlen];

}

}

free(outbuf);

CFRelease(keyRef);

return ret;

}

/* END: Encryption with RSA public key */

#pragma mark - 使用私钥字符串解密

/* START: Decryption with RSA private key */

//使用私钥字符串解密

+ (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey{

if (!str) return nil;

NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];

data = [self decryptData:data privateKey:privKey];

NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

return ret;

}

+ (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privKey{

if(!data || !privKey){

return nil;

}

SecKeyRef keyRef = [self addPrivateKey:privKey];

if(!keyRef){

return nil;

}

return [self decryptData:data withKeyRef:keyRef];

}

+ (SecKeyRef)addPrivateKey:(NSString *)key{

NSRange spos = [key rangeOfString:@"-----BEGIN RSA PRIVATE KEY-----"];

NSRange epos = [key rangeOfString:@"-----END RSA PRIVATE KEY-----"];

if(spos.location != NSNotFound && epos.location != NSNotFound){

NSUInteger s = spos.location + spos.length;

NSUInteger e = epos.location;

NSRange range = NSMakeRange(s, e-s);

key = [key substringWithRange:range];

}

key = [key stringByReplacingOccurrencesOfString:@"\r" withString:@""];

key = [key stringByReplacingOccurrencesOfString:@"\n" withString:@""];

key = [key stringByReplacingOccurrencesOfString:@"\t" withString:@""];

key = [key stringByReplacingOccurrencesOfString:@" "  withString:@""];

// This will be base64 encoded, decode it.

NSData *data = base64_decode(key);

data = [self stripPrivateKeyHeader:data];

if(!data){

return nil;

}

//a tag to read/write keychain storage

NSString *tag = @"RSAUtil_PrivKey";

NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]];

// Delete any old lingering key with the same tag

NSMutableDictionary *privateKey = [[NSMutableDictionary alloc] init];

[privateKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass];

[privateKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];

[privateKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag];

SecItemDelete((__bridge CFDictionaryRef)privateKey);

// Add persistent version of the key to system keychain

[privateKey setObject:data forKey:(__bridge id)kSecValueData];

[privateKey setObject:(__bridge id) kSecAttrKeyClassPrivate forKey:(__bridge id)

kSecAttrKeyClass];

[privateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)

kSecReturnPersistentRef];

CFTypeRef persistKey = nil;

OSStatus status = SecItemAdd((__bridge CFDictionaryRef)privateKey, &persistKey);

if (persistKey != nil){

CFRelease(persistKey);

}

if ((status != noErr) && (status != errSecDuplicateItem)) {

return nil;

}

[privateKey removeObjectForKey:(__bridge id)kSecValueData];

[privateKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];

[privateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];

[privateKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];

// Now fetch the SecKeyRef version of the key

SecKeyRef keyRef = nil;

status = SecItemCopyMatching((__bridge CFDictionaryRef)privateKey, (CFTypeRef *)&keyRef);

if(status != noErr){

return nil;

}

return keyRef;

}

+ (NSData *)stripPrivateKeyHeader:(NSData *)d_key{

// Skip ASN.1 private key header

if (d_key == nil) return(nil);

unsigned long len = [d_key length];

if (!len) return(nil);

unsigned char *c_key = (unsigned char *)[d_key bytes];

unsigned int  idx     = 22; //magic byte at offset 22

if (0x04 != c_key[idx++]) return nil;

//calculate length of the key

unsigned int c_len = c_key[idx++];

int det = c_len & 0x80;

if (!det) {

c_len = c_len & 0x7f;

} else {

int byteCount = c_len & 0x7f;

if (byteCount + idx > len) {

//rsa length field longer than buffer

return nil;

}

unsigned int accum = 0;

unsigned char *ptr = &c_key[idx];

idx += byteCount;

while (byteCount) {

accum = (accum << 8) + *ptr;

ptr++;

byteCount--;

}

c_len = accum;

}

// Now make a new NSData from this buffer

return [d_key subdataWithRange:NSMakeRange(idx, c_len)];

}

+ (NSData *)decryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{

const uint8_t *srcbuf = (const uint8_t *)[data bytes];

size_t srclen = (size_t)data.length;

size_t block_size = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t);

UInt8 *outbuf = malloc(block_size);

size_t src_block_size = block_size;

NSMutableData *ret = [[NSMutableData alloc] init];

for(int idx=0; idx<srclen; idx+=src_block_size){

//NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);

size_t data_len = srclen - idx;

if(data_len > src_block_size){

data_len = src_block_size;

}

size_t outlen = block_size;

OSStatus status = noErr;

status = SecKeyDecrypt(keyRef,

kSecPaddingNone,

srcbuf + idx,

data_len,

outbuf,

&outlen

);

if (status != 0) {

NSLog(@"SecKeyEncrypt fail. Error Code: %d", status);

ret = nil;

break;

}else{

//the actual decrypted data is in the middle, locate it!

int idxFirstZero = -1;

int idxNextZero = (int)outlen;

for ( int i = 0; i < outlen; i++ ) {

if ( outbuf[i] == 0 ) {

if ( idxFirstZero < 0 ) {

idxFirstZero = i;

} else {

idxNextZero = i;

break;

}

}

}

[ret appendBytes:&outbuf[idxFirstZero+1] length:idxNextZero-idxFirstZero-1];

}

}

free(outbuf);

CFRelease(keyRef);

return ret;

}

/* END: Decryption with RSA private key */

@end

使用说明:

  1. 将此.h和.m文件直接复制,并拖到工程中;
  2. 加密和解密需要对应的私钥和公钥(是.der的文件);
  3. 使用:

    NSString *public_key_path = [[NSBundle mainBundle] pathForResource:@"pub.der" ofType:nil];

    NSString *str = [NSString stringWithFormat:@"account=%@&passwd=%@",name,pwd];

    NSString *requestidEncryptStr = [RSAEncryptor encryptString:str publicKeyWithContentsOfFile:public_key_path];

    NSLog(@"加密前 %@",str);

    NSLog(@"加密后 %@",requestidEncryptStr);

    NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:requestidEncryptStr, @"input", nil];

    [self xjpostDic:dic withRequestid:requestid onSuccess:success onFailure:failure];

  4. 这个是加密过程,pub.der是加密使用的公钥。

转载于:https://www.cnblogs.com/wangxiaojingtl/p/6722950.html

关于OPENSSL的使用相关推荐

  1. Linux+Apache2+openssl实现https验证

    首先安装SSL,再编译安装APACHE,再配置证书即可 1.下载apache和openssl 网址:http://www.apache.org       http://www.openssl.org ...

  2. 通过OpenSSL的接口实现Base64编解码

    对openssl genrsa产生的rsa私钥pem文件,使用普通的base64解码会有问题,如使用https://blog.csdn.net/fengbingchun/article/details ...

  3. ASN.1简介及OpenSSL中ASN.1接口使用举例

    ASN.1(Abstract Syntax Notation One)是一套标准,是描述数据的表示.编码传输.解码的灵活的记法.它提供了一套正式.无歧义和精确的规则以描述独立于特定计算机硬件的对象结构 ...

  4. 对称加密算法AES之GCM模式简介及在OpenSSL中使用举例

    AES(Advanced Encryption Standard)即高级加密标准,由美国国家标准和技术协会(NIST)于2000年公布,它是一种对称加密算法.关于AES的更多介绍可以参考:https: ...

  5. 基于Hash的消息认证码HMAC简介及在OpenSSL中使用举例

    HMAC(Hash-based Message Authentication Code):基于Hash的消息认证码,是一种通过特别计算方式之后产生的消息认证码(MAC),使用密码散列函数,同时结合一个 ...

  6. Ubuntu下使用CMake编译OpenSSL源码操作步骤(C语言)

    OpenSSL的版本为1.0.1g,在ubuntu下通过CMake仅编译c代码不包括汇编代码,脚本内容如下: build.sh内容: #! /bin/bashreal_path=$(realpath ...

  7. 非对称加密算法之RSA介绍及OpenSSL中RSA常用函数使用举例

    RSA算法,在1977年由Ron Rivest.Adi Shamirh和LenAdleman,在美国的麻省理工学院开发完成.这个算法的名字,来源于三位开发者的名字.RSA已经成为公钥数据加密标准. R ...

  8. OpenSSL中对称加密算法DES常用函数使用举例

    主要包括3个文件: 1. cryptotest.h: #ifndef _CRYPTOTEST_H_ #define _CRYPTOTEST_H_#include <string>using ...

  9. OpenSSL简介及在Windows、Linux、Mac系统上的编译步骤

    OpenSSL介绍:OpenSSL是一个强大的安全套接字层密码库,囊括主要的密码算法.常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用. SSL是SecureSock ...

  10. 【救援过程】升级openssl导致libcrypto.so.1.1动态库不可用

    目录 一.故障重现 二.救援过程 一.故障重现 近日为了解决CVE-2021-3449: 拒绝服务漏洞.CVE-2021-3450: 证书校验漏洞,自己编译了openssl-1.1.1k. 亲测发现: ...

最新文章

  1. mybatis内部类映射写法
  2. 信号与系统与c语言,2016年安徽医科大学生命科学学院信号系统与C语言程序设计之信号与系统复试笔试仿真模拟题...
  3. Javascript 正则表达式对象
  4. carlife android 无线,carlife无线连接流程是什么
  5. html同学录设计模板,同学录封面
  6. 自锁时间电路plc_PLC对两台三相交流电动机联锁启停控制
  7. PyTorch 1.0 中文文档:torch.cuda
  8. rabbitmq direct 多个消费者_RabbitMQ从零开始
  9. Linux 下配置 node + mongodb 环境
  10. 天梯—判断素数(C语言)
  11. 自学python好找工作么-学完Python好找工作吗?为什么有人学完找不到工作?
  12. 无法完成验证,可能QQ文件已损坏,您需要重新安装QQ
  13. 一个新的专用浏览器-我的意思是Browzar-不能像宣传的那样工作
  14. 【Java爬虫】爬取淘宝买家秀
  15. sns分享 jia.js的使用 jiathis插件
  16. linux.zip文件怎么解压,linux怎么解压zip文件
  17. PDF文件格式转换攻略:PDF格式转换图片格式
  18. F和弦(大横按)的训练方法
  19. 微信iOS WKWebview 网页开发适配指南
  20. 2022最新软件测试面试题(含答案)

热门文章

  1. timespan怎么比较大小_钻石吊坠回收怎么选择大小?
  2. python分割字符串输出_python字符串分割
  3. Linux Socket API Connect 函数详解
  4. java 计算信度,11.5.2 评分者信度实例分析
  5. python的requests模块功能_python中requests模块的使用方法
  6. MATLAB求解非线性方程组
  7. java private 对象_[Java笔记]类的所有构造器都是private权限,就一定没有办法实例化它的对象了么?...
  8. PyTorch的13个必知必会知识点
  9. u32转换bool类型_4.29.类型转换
  10. 计算机转正述职报告ppt,转正述职报告ppt