美文网首页
RSA非对称加密

RSA非对称加密

作者: 倪大头 | 来源:发表于2019-06-24 15:16 被阅读0次

服务端配发公钥给客户端,客户端把加密的数据传回服务端,服务端用私钥解密

工具类:

DTRSAEncryptor.h
用传入的公钥加密

#import <Foundation/Foundation.h>

@interface DTRSAEncryptor : NSObject

+ (void)setSharedInstance:(DTRSAEncryptor *)instance;

+ (DTRSAEncryptor *)sharedInstance;

- (void)loadPublicKeyFromFile:(NSString *)derFilePath;

- (void)loadPublicKeyFromData:(NSData *)derData;

- (void)loadPrivateKeyFromFile:(NSString *)p12FilePath password:(NSString *)p12Password;

- (void)loadPrivateKeyFromData:(NSData *)p12Data password:(NSString *)p12Password;

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

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

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

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

@end

DTRSAEncryptor.m

#import "DTRSAEncryptor.h"
#import "NSData+Base64.h"

@implementation DTRSAEncryptor
{
    SecKeyRef publicKey;
    SecKeyRef privateKey;
}

static DTRSAEncryptor *sharedInstance = nil;

+ (void)setSharedInstance:(DTRSAEncryptor *)instance {
    sharedInstance = instance;
}

+ (DTRSAEncryptor *)sharedInstance {
    return sharedInstance;
}

- (SecKeyRef)getPublicKey {
    return publicKey;
}

- (SecKeyRef)getPrivateKey {
    return privateKey;
}

- (void)loadPublicKeyFromFile:(NSString *)derFilePath {
    NSData *derData = [[NSData alloc] initWithContentsOfFile:derFilePath];
    [self loadPublicKeyFromData:derData];
}

- (void)loadPublicKeyFromData:(NSData *)derData {
    publicKey = [self getPublicKeyRefrenceFromeData:derData];
}

- (void)loadPrivateKeyFromFile:(NSString *)p12FilePath password:(NSString *)p12Password {
    NSData *p12Data = [NSData dataWithContentsOfFile:p12FilePath];
    [self loadPrivateKeyFromData: p12Data password:p12Password];
}

- (void)loadPrivateKeyFromData:(NSData *) p12Data password:(NSString *)p12Password {
    privateKey = [self getPrivateKeyRefrenceFromData:p12Data password:p12Password];
}

#pragma mark - Private Methods
- (SecKeyRef)getPublicKeyRefrenceFromeData:(NSData *)derData {
    SecCertificateRef myCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)derData);
    SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
    SecTrustRef myTrust;
    OSStatus status = SecTrustCreateWithCertificates(myCertificate,myPolicy,&myTrust);
    SecTrustResultType trustResult;
    if (status == noErr) {
        status = SecTrustEvaluate(myTrust, &trustResult);
    }
    SecKeyRef securityKey = SecTrustCopyPublicKey(myTrust);
    CFRelease(myCertificate);
    CFRelease(myPolicy);
    CFRelease(myTrust);
    
    return securityKey;
}

- (SecKeyRef)getPrivateKeyRefrenceFromData:(NSData *)p12Data password:(NSString *)password {
    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;
}

#pragma mark - Encrypt
- (NSString *)rsaEncryptString:(NSString *)string {
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    NSData *encryptedData = [self rsaEncryptData:data];
    NSString *base64EncryptedString = [encryptedData base64EncodeDataToNSString];
    
    return base64EncryptedString;
}

//加密的大小受限于SecKeyEncrypt函数,SecKeyEncrypt要求明文和密钥的长度一致,如果要加密更长的内容,需要把内容按密钥长度分成多份,然后多次调用SecKeyEncrypt来实现
- (NSData *)rsaEncryptData:(NSData *)data {
    SecKeyRef key = [self getPublicKey];
    size_t cipherBufferSize = SecKeyGetBlockSize(key);
    uint8_t *cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
    size_t blockSize = cipherBufferSize - 11;       // 分段加密
    size_t blockCount = (size_t)ceil([data length] / (double)blockSize);
    NSMutableData *encryptedData = [[NSMutableData alloc] init] ;
    for (int i=0; i<blockCount; i++) {
        int bufferSize = (int)(MIN(blockSize,[data length] - i * blockSize));
        NSData *buffer = [data subdataWithRange:NSMakeRange(i * blockSize, 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;
}

#pragma mark - Decrypt
- (NSString *)rsaDecryptString:(NSString *)string {
    NSData *data = [NSData dataWithBase64EncodedNSString:string];
    NSData *decryptData = [self rsaDecryptData:data];
    NSString *result = [[NSString alloc] initWithData:decryptData encoding:NSUTF8StringEncoding];
    return result;
}

- (NSData *)rsaDecryptData:(NSData *)data {
    SecKeyRef key = [self getPrivateKey];
    size_t cipherLen = [data length];
    void *cipher = malloc(cipherLen);
    [data getBytes:cipher length:cipherLen];
    size_t plainLen = SecKeyGetBlockSize(key) - 12;
    void *plain = malloc(plainLen);
    OSStatus status = SecKeyDecrypt(key, kSecPaddingPKCS1, cipher, cipherLen, plain, &plainLen);
    
    if (status != noErr) {
        return nil;
    }
    
    NSData *decryptedData = [[NSData alloc] initWithBytes:(const void *)plain length:plainLen];
    
    return decryptedData;
}


- (void)dealloc {
    CFRelease(publicKey);
    CFRelease(privateKey);
}


@end

DTRSATool.h
这个类用来把公钥传给DTRSAEncryptor类

#import <Foundation/Foundation.h>

@interface DTRSATool : NSObject

//加密数据
- (NSString *)encryData:(NSString *)str;

@end

DTRSATool.m

#import "DTRSATool.h"
#import "DTRSAEncryptor.h"

@implementation DTRSATool

//加密数据
- (NSString *)encryData:(NSString *)str {
    DTRSAEncryptor *rsaEncryptor = [[DTRSAEncryptor alloc] init];
    NSString *publicKeyPath = [[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"];
    [rsaEncryptor loadPublicKeyFromFile:publicKeyPath];
    
    NSString *returnBASE64STRING = [rsaEncryptor rsaEncryptString:str];
    NSLog(@"加密后的: %@", returnBASE64STRING);//加密
    
    NSString *privateKeyPath = [[NSBundle mainBundle] pathForResource:@"private_key" ofType:@"p12"];
    [rsaEncryptor loadPrivateKeyFromFile:privateKeyPath password:@"123456"];
    
    NSString *decryptString = [rsaEncryptor rsaDecryptString:returnBASE64STRING];//解密
    NSLog(@"解密后的: %@", decryptString);
    
    return returnBASE64STRING;
}

@end

使用方法:

NSDictionary *dic = @{@"firstparam": @"第一个参数", @"secondparam": @"第二个参数"};
    
DTRSATool *rsaTool = [[DTRSATool alloc] init];
NSError *error = nil;
NSData *paramsData = [NSJSONSerialization dataWithJSONObject:dic options:kNilOptions error:&error];
NSString *paramsJsonString = [[NSString alloc] initWithData:paramsData encoding:NSUTF8StringEncoding];
NSString *encryParamsStr = [rsaTool encryData:paramsJsonString];

encryParamsStr就是加密好的字符串了

相关文章

  • kotlin版本RSA非对称加密解密与分段加密解密

    基于kotlin语言的RSA非对称加密解密与分段加密解密 RSA非对称加密 RSA非对称加密的具体算法与来源我就不...

  • 非对称加密算法RSA 学习

    非对称加密算法RSA 学习 RSA加密算法是一种非对称加密算法。RSA是1977年由罗纳德·李维斯特(Ron Ri...

  • RSA加密

    RSA加密为非对称加密实现 对称加密:加密解密使用同一个算法 非对称加密:加密和解密使用不同算法 rsa加密原理 ...

  • 3.2 RSA算法简介

    非对称加密技术 -- RSA算法 RSA算法是流行最广泛的非对称加密算法,也是唯一的基于因式分解的非对称加密算法。...

  • 非对称加密

    非对称加密 非对称加密算法有:RSA,DSA,ECC,DH.其中RSA最为常用. 非对称加密一般有一对公钥和私钥,...

  • RSA非对称加密

    RSA非对称加密 RSA非对称加密, 适用于Java和iOS 应用场景:用户登录时对登录密码进行加密 启动终端, ...

  • 6.1 密码学专题 - 非对称加密算法 - RSA 算法

    密码学专题 - 非对称加密算法 - RSA 算法 6.1 RSA 算法 第一个较完善的非对称加密算法 RSA,它既...

  • iOS-对称加密和(rsa)非对称加密

    说起rsa,大家自然就会说,非对称加密嘛。是的,rsa非对称加密算是安全级别非常高的加密方式,至少对于现在而言。这...

  • 密码学基础(三):非对称加密(RSA算法原理)

    什么是RSA加密 加密和解密使用的是两个不同的秘钥,这种算法叫做非对称加密。非对称加密又称为公钥加密,RSA只是公...

  • ios开发之证书和签名机制(一)

    非对称加密和摘要 1、非对称加密的特性和用法 1) 非对称加密算法(RSA):非对称加密算法指加密秘钥和解密秘钥是...

网友评论

      本文标题:RSA非对称加密

      本文链接:https://www.haomeiwen.com/subject/lrcoqctx.html