IOS中RSA的加密解密(转载)

来源:互联网 发布:淘宝钻石展位是什么 编辑:程序博客网 时间:2024/05/16 15:19

转载自:http://blog.csdn.net/marujunyy/article/details/39079955


1. 生成私钥openssl req -x509 -days 3650 -new -newkey rsa:2048 -keyout private_key.pem -out private_key.pem

2. 生成p12格式的文件openssl pkcs12 -export -out private_pkcs.p12 -in private_key.pem

3. 生成自签名证书openssl x509 -in private_key.pem -inform PEM -out public_key.der -outform DER


使用到的第三方库:https://github.com/nicklockwood/Base64


    //原始字符串    NSString *value = @"测试iOS中RSA加密和解密";        //加密    NSString *encrypt= [value rsaEncrypt];    FLOG(@"encrypted string: %@",encrypt);        //解密    NSString *decrypt= [encrypt rsaDecrypt];    FLOG(@"decrypted string: %@",decrypt);



类文件:

////  RSA.h//  MCFriends////  Created by marujun on 14-9-4.//  Copyright (c) 2014年 marujun. All rights reserved.//#import <Foundation/Foundation.h>#import "Base64.h"@interface RSA : NSObject+ (NSString *)encryptWithString:(NSString *)content;+ (NSString *)decryptWithString:(NSString *)content;@end@interface NSString (RSA)- (NSString *)rsaEncrypt;- (NSString *)rsaDecrypt;@end



////  RSA.m//  MCFriends////  Created by marujun on 14-9-4.//  Copyright (c) 2014年 marujun. All rights reserved.//#import "RSA.h"@implementation RSAstatic SecKeyRef _publicKey = nil;+ (SecKeyRef)getPublicKey{    // 从公钥证书文件中获取到公钥的SecKeyRef指针    if(_publicKey == nil){        NSData *certificateData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"]];                SecCertificateRef myCertificate =  SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certificateData);        SecPolicyRef myPolicy = SecPolicyCreateBasicX509();        SecTrustRef myTrust;        OSStatus status = SecTrustCreateWithCertificates(myCertificate,myPolicy,&myTrust);        SecTrustResultType trustResult;        if (status == noErr) {            status = SecTrustEvaluate(myTrust, &trustResult);        }        _publicKey = SecTrustCopyPublicKey(myTrust);        CFRelease(myCertificate);        CFRelease(myPolicy);        CFRelease(myTrust);    }    return _publicKey;}+ (NSString *)encryptWithString:(NSString *)content{    SecKeyRef key = [self getPublicKey];        // 分配内存块,用于存放加密后的数据段    size_t cipherBufferSize = SecKeyGetBlockSize(key);    uint8_t *cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));    NSData *stringBytes = [content dataUsingEncoding:NSUTF8StringEncoding];    size_t blockSize = cipherBufferSize - 12;    size_t blockCount = (size_t)ceil([stringBytes length] / (double)blockSize);        NSMutableData *encryptedData = [NSMutableData data];    // 分段加密    for (int i = 0; i < blockCount; i++) {        NSUInteger loc = i * blockSize;        // 数据段的实际大小。最后一段可能比blockSize小。        int bufferSize = MIN(blockSize,[stringBytes length] - loc);        // 截取需要加密的数据段        NSData *buffer = [stringBytes subdataWithRange:NSMakeRange(loc, bufferSize)];        OSStatus status = SecKeyEncrypt(key, kSecPaddingPKCS1, (const uint8_t *)[buffer bytes], [buffer length], cipherBuffer, &cipherBufferSize);        if (status == noErr) {            NSData *encryptedBytes = [[NSData alloc] initWithBytes:(const void *)cipherBuffer length:cipherBufferSize];            // 追加加密后的数据段            [encryptedData appendData:encryptedBytes];        } else {            if (cipherBuffer) {                free(cipherBuffer);            }            return nil;        }    }    if (cipherBuffer) {        free(cipherBuffer);    }    return [encryptedData base64EncodedString];}static SecKeyRef _privateKey = nil;+ (SecKeyRef)getPrivateKey{    // 从p12文件中获取到私钥的SecKeyRef指针    if(_privateKey == nil){        NSString *pkcsPassword = @"****"; //p12文件密码        NSData *p12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"private_pkcs" ofType:@"p12"]]; //p12文件路径                CFStringRef password = (__bridge 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);        OSStatus status = SecPKCS12Import((__bridge CFDataRef)p12Data, options, &items);        if (status == errSecSuccess) {            CFDictionaryRef identity_trust_dic = CFArrayGetValueAtIndex(items, 0);            SecIdentityRef identity = (SecIdentityRef)CFDictionaryGetValue(identity_trust_dic, kSecImportItemIdentity);            SecTrustRef trust = (SecTrustRef)CFDictionaryGetValue(identity_trust_dic, kSecImportItemTrust);            // certs数组中包含了所有的证书            CFArrayRef certs = (CFArrayRef)CFDictionaryGetValue(identity_trust_dic, kSecImportItemCertChain);            if ([(__bridge NSArray *)certs count] && trust && identity) {                // 如果没有下面一句,自签名证书的评估信任结果永远是kSecTrustResultRecoverableTrustFailure                status = SecTrustSetAnchorCertificates(trust, certs);                if (status == noErr) {                    SecTrustResultType trustResultType;                    // 通常, 返回的trust result type应为kSecTrustResultUnspecified,如果是,就可以说明签名证书是可信的                    status = SecTrustEvaluate(trust, &trustResultType);                    if ((trustResultType == kSecTrustResultUnspecified || trustResultType == kSecTrustResultProceed) && status == errSecSuccess) {                        // 证书可信,可以提取私钥与公钥,然后可以使用公私钥进行加解密操作                        status = SecIdentityCopyPrivateKey(identity, &_privateKey);                        if (status == noErr && _privateKey) {                            // 成功提取私钥                        }                    }                }            }        }        if (options) {            CFRelease(options);        }    }    return _privateKey;}+ (NSString *)decryptWithString:(NSString *)content{    SecKeyRef key = [self getPrivateKey];        // 分配内存块,用于存放解密后的数据段    size_t plainBufferSize = SecKeyGetBlockSize(key);    uint8_t *plainBuffer = malloc(plainBufferSize * sizeof(uint8_t));    NSData *cipherData = [content base64DecodedData];        // 计算数据段最大长度及数据段的个数    size_t blockSize = plainBufferSize;    size_t blockCount = (size_t)ceil([cipherData length] / blockSize);        NSMutableData *decryptedData = [NSMutableData data];    // 分段解密    for (int i = 0; i < blockCount; i++) {        NSUInteger loc = i * blockSize;        // 数据段的实际大小。最后一段可能比blockSize小。        int bufferRealSize = MIN(blockSize, [cipherData length] - loc);        // 截取需要解密的数据段        NSData *buffer = [cipherData subdataWithRange:NSMakeRange(loc, bufferRealSize)];        OSStatus status = SecKeyDecrypt(key, kSecPaddingPKCS1, (const uint8_t *)[buffer bytes], [buffer length], plainBuffer, &plainBufferSize);        if (status == noErr) {            NSData *decryptedBytes = [[NSData alloc] initWithBytes:(const void *)plainBuffer length:plainBufferSize];            [decryptedData appendData:decryptedBytes];        } else {            if (plainBuffer) {                free(plainBuffer);            }            return nil;        }    }    if (plainBuffer) {        free(plainBuffer);    }    return  [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];;}@end@implementation NSString (RSA)- (NSString *)rsaEncrypt{    return [RSA encryptWithString:self];}- (NSString *)rsaDecrypt{    return [RSA decryptWithString:self];}@end



0 0
原创粉丝点击