#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. 金华杭州计算机学校录取分数线,2017年浙江金华各地中考录取分数线
  2. SQL Server 2008企业试用版到期,升级为企业版
  3. python基础框架_Python基础框架和工具-阿里云开发者社区
  4. 了解一下Cookie吧
  5. Xshell操控kali-linux虚拟机
  6. python 点滴记录1:python没有Tkinter模块
  7. RGBD论文阅读笔记
  8. PopTheBubble —测量媒体偏差的产品创意
  9. Django之kindeditor
  10. ubuntu运行c/c++语言
  11. UNITY游戏开发源码
  12. yyuc php,yyuc 开发手册.zip 框架 说明指南 Windows Develop 238万源代码下载- www.pudn.com...
  13. Quartz 数据库表
  14. 《计算机网络》——IEEE 802.11 无线局域网、无线局域网的分类、广域网、PPP协议、HDLC协议、链路层设备、冲突域和广播域
  15. 【水滴云|热点】个人信息安全有法可依,海量数据用IPFS存储
  16. C++内存模型以及寄存器指针rsp和rbp
  17. 练习-Java输入输出之字节数据输入输出之综合练习
  18. 生成全排列算法的实现(Johnson-Trotter)
  19. Linux报错-ssh_exchange_identi...
  20. deepin安装docker

热门文章

  1. Linux umask限制导致php的mkdir 0777无效
  2. 上周热点回顾(9.1-9.7)
  3. 中文(英译) 爱情一句话哲理
  4. web策略类游戏开发(四)一个可以承载万人在线的架构
  5. ubuntu 重定向
  6. tf.reshape()
  7. Linux--date命令 date命令
  8. 透明怎么弄_最新版微信如何设置透明背景?这样设置,效果令人惊喜
  9. c语言编译时检查逻辑错误吗,C语言陷阱与技巧20节,自定义“编译时”assert方法,在代码编译阶段检查“逻辑”错误...
  10. android 启动页_App启动优化一顿操作猛如虎