RSA 加密

来源:互联网 发布:可牛影像mac版 编辑:程序博客网 时间:2024/05/23 01:41
  • 首先我们要会生成RSA密钥文件,现在一步步的来给大家展示一下,如何生成我们所需的公钥和私钥文件:
    RSA密钥生成过程
  • 生成私钥文件
    $ openssl genrsa -out private.pem 1024
    • openssl:是一个自由的软件组织,专注做加密和解密的框架。
    • genrsa:指定了生成了算法使用RSA
    • -out:后面的参数表示生成的key的输入文件
    • 1024:表示的是生成key的长度,单位字节(bits)
  • 创建证书请求
    $ openssl req -new -key private.pem -out rsacert.csr
    • 可以拿着这个文件去数字证书颁发机构(即CA)申请一个数字证书。CA会给你一个新的文件cacert.pem,那才是你的数字证书。(要收费的)
  • 生成证书并签名,有效期10年
    $ openssl x509 -req -days 3650 -in rsacert.csr -signkey private.pem -out rsacert.crt
    • 509是一种非常通用的证书格式。
    • 将用上面生成的密钥privkey.pem和rsacert.csr证书请求文件生成一个数字证书rsacert.crt。这个就是公钥
  • 转换格式 将 PEM 格式文件 转换成 DER 格式
    $ openssl x509 -outform der -in rsacert.crt -out rsacert.der
    • 在 iOS开发中,公钥是不能使用base64编码的,上面的命令是将公钥的base64编码字符串转换成二进制数据
  • 导出 P12 文件
    • 在iOS使用私钥不能直接使用,需要导出一个p12文件。下面命令就是将私钥文件导出为p12文件。

$ openssl pkcs12 -export -out p.p12 -inkey private.pem -in rsacert.crt


执行完上面的这些,我们现在就得到了四个文件 



  • 那么接下来,我们用这两个文件来使用一下(小点点的两个文件即可)。

 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

    //创建加密对象

    CryptorTools *tool = [[CryptorTools alloc]init];

    //要加密的内容

    NSString *msg = @"i love you";

    //加载公钥

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

    [tool loadPublicKeyWithFilePath:pubPath];

    //使用公钥加密

    NSString *result = [tool RSAEncryptString:msg];

    NSLog(@"加密 = %@",result);



    //解密

    //加载私钥

    //密码是导出p12密码

    NSString *privatePath = [[NSBundle mainBundle] pathForResource:@"p.p12" ofType:nil];

    [tool loadPrivateKey:privatePath password:@"123456 "];

    //使用私钥解密

    NSString *result2 = [tool RSADecryptString:result];

    NSLog(@"解密 = %@",result2);

}




//

//  CryptorTools.h

//  加密/解密工具

//

//  Created by ZZQ on 15/8/6.

//  Copyright (c) 2015 ZZQ. All rights reserved.

//


#import <Foundation/Foundation.h>


///  加密工具类

///  提供RSA & AES & DES加密方法

@interface CryptorTools : NSObject


#pragma mark - DES 加密/解密

///  DES 加密

///

///  @param data      要加密的二进制数据

///  @param keyString 加密密钥

///  @param iv        IV向量

///

///  @return 加密后的二进制数据

+ (NSData *)DESEncryptData:(NSData *)data keyString:(NSString *)keyString iv:(NSData *)iv;


///  DES 加密字符串

///

///  @param string    要加密的字符串

///  @param keyString 加密密钥

///  @param iv        IV向量

///

///  @return 加密后的 BASE64编码字符串

+ (NSString *)DESEncryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;


///  DES 解密

///

///  @param data      要解密的二进制数据

///  @param keyString 解密密钥

///  @param iv        IV向量

///

///  @return 解密后的二进制数据

+ (NSData *)DESDecryptData:(NSData *)data keyString:(NSString *)keyString iv:(NSData *)iv;


///  DES 解密

///

///  @param string    要解密的 BASE64编码字符串

///  @param keyString 解密密钥

///  @param iv        IV向量

///

///  @return 解密后的二进制数据

+ (NSString *)DESDecryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;


#pragma mark - AES 加密/解密

///  AES 加密

///

///  @param data      要加密的二进制数据

///  @param keyString 加密密钥

///  @param iv        IV向量

///

///  @return 加密后的二进制数据

+ (NSData *)AESEncryptData:(NSData *)data keyString:(NSString *)keyString iv:(NSData *)iv;


///  AES 加密字符串

///

///  @param string    要加密的字符串

///  @param keyString 加密密钥

///  @param iv        IV向量

///

///  @return 加密后的 BASE64编码字符串

+ (NSString *)AESEncryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;


///  AES 解密

///

///  @param data      要解密的二进制数据

///  @param keyString 解密密钥

///  @param iv        IV向量

///

///  @return 解密后的二进制数据

+ (NSData *)AESDecryptData:(NSData *)data keyString:(NSString *)keyString iv:(NSData *)iv;


///  AES 解密

///

///  @param string    要解密的 BASE64编码字符串

///  @param keyString 解密密钥

///  @param iv        IV向量

///

///  @return 解密后的二进制数据

+ (NSString *)AESDecryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;


#pragma mark - RSA 加密/解密算法

///  加载公钥

///

///  @param filePath DER 公钥文件路径

- (void)loadPublicKeyWithFilePath:(NSString *)filePath;


///  加载私钥

///

///  @param filePath P12 私钥文件路径

///  @param password P12 密码

- (void)loadPrivateKey:(NSString *)filePath password:(NSString *)password;


///  RSA 加密数据

///

///  @param data 要加密的数据

///

///  @return 加密后的二进制数据

- (NSData *)RSAEncryptData:(NSData *)data;


///  RSA 加密字符串

///

///  @param string 要加密的字符串

///

///  @return 加密后的 BASE64编码字符串

- (NSString *)RSAEncryptString:(NSString *)string;


///  RSA 解密数据

///

///  @param data 要解密的数据

///

///  @return 解密后的二进制数据

- (NSData *)RSADecryptData:(NSData *)data;


///  RSA 解密字符串

///

///  @param string 要解密的 BASE64编码字符串

///

///  @return 解密后的字符串

- (NSString *)RSADecryptString:(NSString *)string;


@end



=================================



//

//  CryptorTools.m

//  加密/解密工具

//

//  Created by ZZQ on 15/8/6.

//  Copyright (c) 2015 ZZQ. All rights reserved.

//


#import "CryptorTools.h"

#import <CommonCrypto/CommonCrypto.h>


// 填充模式

#define kTypeOfWrapPadding      kSecPaddingPKCS1


@interface CryptorTools() {

    SecKeyRef _publicKeyRef;                            // 公钥引用

    SecKeyRef _privateKeyRef;                           // 私钥引用

}


@end


@implementation CryptorTools


#pragma mark - DES 加密/解密

#pragma mark 加密

+ (NSData *)DESEncryptData:(NSData *)data keyString:(NSString *)keyString iv:(NSData *)iv {

    return [selfCCCryptData:data algorithm:kCCAlgorithmDESoperation:kCCEncryptkeyString:keyString iv:iv];

}


+ (NSString *)DESEncryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {

    NSData *data = [stringdataUsingEncoding:NSUTF8StringEncoding];

    NSData *result = [selfDESEncryptData:data keyString:keyStringiv:iv];

    

    // BASE 64 编码

    return [resultbase64EncodedStringWithOptions:0];

}


#pragma mark 解密

+ (NSData *)DESDecryptData:(NSData *)data keyString:(NSString *)keyString iv:(NSData *)iv {

    return [selfCCCryptData:data algorithm:kCCAlgorithmDESoperation:kCCDecryptkeyString:keyString iv:iv];

}


+ (NSString *)DESDecryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {

    // BASE 64 解码

    NSData *data = [[NSDataalloc] initWithBase64EncodedString:stringoptions:0];

    NSData *result = [selfDESDecryptData:data keyString:keyStringiv:iv];

    

    return [[NSStringalloc] initWithData:resultencoding:NSUTF8StringEncoding];

}


#pragma mark - AES 加密/解密

#pragma mark 加密

+ (NSData *)AESEncryptData:(NSData *)data keyString:(NSString *)keyString iv:(NSData *)iv   {

    return [selfCCCryptData:data algorithm:kCCAlgorithmAESoperation:kCCEncryptkeyString:keyString iv:iv];

}


+ (NSString *)AESEncryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {

    NSData *data = [stringdataUsingEncoding:NSUTF8StringEncoding];

    NSData *result = [selfAESEncryptData:data keyString:keyStringiv:iv];

    

    // BASE 64 编码

    return [resultbase64EncodedStringWithOptions:0];

}


#pragma mark 解密

+ (NSData *)AESDecryptData:(NSData *)data keyString:(NSString *)keyString iv:(NSData *)iv {

    return [selfCCCryptData:data algorithm:kCCAlgorithmAESoperation:kCCDecryptkeyString:keyString iv:iv];

}


+ (NSString *)AESDecryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {

    // BASE 64 解码

    NSData *data = [[NSDataalloc] initWithBase64EncodedString:stringoptions:0];

    NSData *result = [selfAESDecryptData:data keyString:keyStringiv:iv];

    

    return [[NSStringalloc] initWithData:resultencoding:NSUTF8StringEncoding];

}


#pragma mark 对称加密&解密核心方法

///  对称加密&解密核心方法

///

///  @param data      加密/解密的二进制数据

///  @param algorithm 加密算法

///  @param operation 加密/解密操作

///  @param keyString 密钥字符串

///  @param iv        IV 向量

///

///  @return 加密/解密结果

+ (NSData *)CCCryptData:(NSData *)data algorithm:(CCAlgorithm)algorithm operation:(CCOperation)operation keyString:(NSString *)keyString iv:(NSData *)iv {

    

    int keySize = (algorithm ==kCCAlgorithmAES) ? kCCKeySizeAES128 :kCCKeySizeDES;

    int blockSize = (algorithm ==kCCAlgorithmAES) ? kCCBlockSizeAES128:kCCBlockSizeDES;

    

    // 设置密钥

    NSData *keyData = [keyStringdataUsingEncoding:NSUTF8StringEncoding];

    uint8_t cKey[keySize];

    bzero(cKey,sizeof(cKey));

    [keyData getBytes:cKeylength:keySize];

    

    // 设置 IV向量

    uint8_t cIv[blockSize];

    bzero(cIv, blockSize);

    int option =kCCOptionPKCS7Padding | kCCOptionECBMode;

    if (iv) {

        [iv getBytes:cIvlength:blockSize];

        option = kCCOptionPKCS7Padding;

    }

    

    // 设置输出缓冲区

    size_t bufferSize = [datalength] + blockSize;

    void *buffer =malloc(bufferSize);

    

    // 加密或解密

    size_t cryptorSize =0;

    CCCryptorStatus cryptStatus =CCCrypt(operation,

                                          algorithm,

                                          option,

                                          cKey,

                                          keySize,

                                          cIv,

                                          [data bytes],

                                          [data length],

                                          buffer,

                                          bufferSize,

                                          &cryptorSize);

    

    NSData *result =nil;

    if (cryptStatus ==kCCSuccess) {

        result = [NSDatadataWithBytesNoCopy:buffer length:cryptorSize];

    } else {

        free(buffer);

        NSLog(@"[错误]加密或解密失败 | 状态编码: %d", cryptStatus);

    }

    

    return result;

}


#pragma mark - RSA 加密/解密算法

- (void)loadPublicKeyWithFilePath:(NSString *)filePath; {

    

    NSAssert(filePath.length !=0, @"公钥路径为空");

    

    // 删除当前公钥

    if (_publicKeyRef)CFRelease(_publicKeyRef);

    

    // 从一个 DER表示的证书创建一个证书对象

    NSData *certificateData = [NSDatadataWithContentsOfFile:filePath];

    SecCertificateRef certificateRef =SecCertificateCreateWithData(kCFAllocatorDefault, (__bridgeCFDataRef)certificateData);

    NSAssert(certificateRef !=NULL, @"公钥文件错误");

    

    // 返回一个默认 X509策略的公钥对象,使用之后需要调用 CFRelease 释放

    SecPolicyRef policyRef =SecPolicyCreateBasicX509();

    // 包含信任管理信息的结构体

    SecTrustRef trustRef;

    

    // 基于证书和策略创建一个信任管理对象

    OSStatus status =SecTrustCreateWithCertificates(certificateRef, policyRef, &trustRef);

    NSAssert(status ==errSecSuccess, @"创建信任管理对象失败");

    

    // 信任结果

    SecTrustResultType trustResult;

    // 评估指定证书和策略的信任管理是否有效

    status = SecTrustEvaluate(trustRef, &trustResult);

    NSAssert(status ==errSecSuccess, @"信任评估失败");

    

    // 评估之后返回公钥子证书

    _publicKeyRef =SecTrustCopyPublicKey(trustRef);

    NSAssert(_publicKeyRef !=NULL, @"公钥创建失败");

    

    if (certificateRef)CFRelease(certificateRef);

    if (policyRef)CFRelease(policyRef);

    if (trustRef)CFRelease(trustRef);

}


- (void)loadPrivateKey:(NSString *)filePath password:(NSString *)password {

    

    NSAssert(filePath.length !=0, @"私钥路径为空");

    

    // 删除当前私钥

    if (_privateKeyRef)CFRelease(_privateKeyRef);

    

    NSData *PKCS12Data = [NSDatadataWithContentsOfFile:filePath];

    CFDataRef inPKCS12Data = (__bridgeCFDataRef)PKCS12Data;

    CFStringRef passwordRef = (__bridgeCFStringRef)password;

    

    // PKCS #12证书中提取标示和证书

    SecIdentityRef myIdentity;

    SecTrustRef myTrust;

    constvoid *keys[] = {kSecImportExportPassphrase};

    constvoid *values[] = {passwordRef};

    CFDictionaryRef optionsDictionary =CFDictionaryCreate(NULL, keys, values,1, NULL,NULL);

    CFArrayRef items =CFArrayCreate(NULL,0, 0,NULL);

    

    // 返回 PKCS #12格式数据中的标示和证书

    OSStatus status =SecPKCS12Import(inPKCS12Data, optionsDictionary, &items);

    

    if (status ==noErr) {

        CFDictionaryRef myIdentityAndTrust =CFArrayGetValueAtIndex(items, 0);

        myIdentity = (SecIdentityRef)CFDictionaryGetValue(myIdentityAndTrust,kSecImportItemIdentity);

        myTrust = (SecTrustRef)CFDictionaryGetValue(myIdentityAndTrust,kSecImportItemTrust);

    }

    

    if (optionsDictionary)CFRelease(optionsDictionary);

    

    NSAssert(status ==noErr, @"提取身份和信任失败");

    

    SecTrustResultType trustResult;

    // 评估指定证书和策略的信任管理是否有效

    status = SecTrustEvaluate(myTrust, &trustResult);

    NSAssert(status ==errSecSuccess, @"信任评估失败");

    

    // 提取私钥

    status = SecIdentityCopyPrivateKey(myIdentity, &_privateKeyRef);

    NSAssert(status ==errSecSuccess, @"私钥创建失败");

    CFRelease(items);

}


- (NSString *)RSAEncryptString:(NSString *)string {

    NSData *cipher = [selfRSAEncryptData:[string dataUsingEncoding:NSUTF8StringEncoding]];

    

    return [cipherbase64EncodedStringWithOptions:0];

}


- (NSData *)RSAEncryptData:(NSData *)data {

    OSStatus sanityCheck =noErr;

    size_t cipherBufferSize =0;

    size_t keyBufferSize =0;

    

    NSAssert(data,@"明文数据为空");

    NSAssert(_publicKeyRef,@"公钥为空");

    

    NSData *cipher =nil;

    uint8_t *cipherBuffer =NULL;

    

    // 计算缓冲区大小

    cipherBufferSize = SecKeyGetBlockSize(_publicKeyRef);

    keyBufferSize = data.length;

    

    if (kTypeOfWrapPadding ==kSecPaddingNone) {

        NSAssert(keyBufferSize <= cipherBufferSize,@"加密内容太大");

    } else {

        NSAssert(keyBufferSize <= (cipherBufferSize -11), @"加密内容太大");

    }

    

    // 分配缓冲区

    cipherBuffer = malloc(cipherBufferSize *sizeof(uint8_t));

    memset((void *)cipherBuffer,0x0, cipherBufferSize);

    

    // 使用公钥加密

    sanityCheck = SecKeyEncrypt(_publicKeyRef,

                                kTypeOfWrapPadding,

                                (constuint8_t *)data.bytes,

                                keyBufferSize,

                                cipherBuffer,

                                &cipherBufferSize

                                );

    

    NSAssert(sanityCheck ==noErr, @"加密错误,OSStatus == %d", sanityCheck);

    

    // 生成密文数据

    cipher = [NSDatadataWithBytes:(constvoid *)cipherBuffer length:(NSUInteger)cipherBufferSize];

    

    if (cipherBuffer)free(cipherBuffer);

    

    return cipher;

}


- (NSString *)RSADecryptString:(NSString *)string {

    NSData *keyData = [selfRSADecryptData:[[NSDataalloc] initWithBase64EncodedString:stringoptions:0]];

    

    return [[NSStringalloc] initWithData:keyDataencoding:NSUTF8StringEncoding];

}


- (NSData *)RSADecryptData:(NSData *)data {

    OSStatus sanityCheck =noErr;

    size_t cipherBufferSize =0;

    size_t keyBufferSize =0;

    

    NSData *key =nil;

    uint8_t *keyBuffer =NULL;

    

    SecKeyRef privateKey =_privateKeyRef;

    NSAssert(privateKey !=NULL, @"私钥不存在");

    

    // 计算缓冲区大小

    cipherBufferSize = SecKeyGetBlockSize(privateKey);

    keyBufferSize = data.length;

    

    NSAssert(keyBufferSize <= cipherBufferSize,@"解密内容太大");

    

    // 分配缓冲区

    keyBuffer = malloc(keyBufferSize *sizeof(uint8_t));

    memset((void *)keyBuffer,0x0, keyBufferSize);

    

    // 使用私钥解密

    sanityCheck = SecKeyDecrypt(privateKey,

                                kTypeOfWrapPadding,

                                (constuint8_t *)data.bytes,

                                cipherBufferSize,

                                keyBuffer,

                                &keyBufferSize

                                );

    

    NSAssert1(sanityCheck == noErr,@"解密错误,OSStatus == %d", sanityCheck);

    

    // 生成明文数据

    key = [NSDatadataWithBytes:(constvoid *)keyBuffer length:(NSUInteger)keyBufferSize];

    

    if (keyBuffer)free(keyBuffer);

    

    return key;

}


@end


0 0