經過ios實現RSA加密和解密

在加密和解密中,咱們須要瞭解的知識有什麼事openssl;RSA加密算法的基本原理;如何經過openssl生成最後咱們須要的der和p12文件。git

廢話很少說,直接寫步驟:算法

第一步:openssl來生成公鑰和私鑰證書,最後須要獲得公鑰證書和私鑰證書數據結構

app

這是在mac OX系統下顯示的證書,若是咱們用文本編輯器打開它,會發現裏面是----BEGIN RSA 開頭  而且----END RSA 結尾的一串字符串。 編輯器

第二步:咱們須要在代碼中寫咱們的加密和機密方法,加密的字符串經過公鑰進行加密,加密後的字符串也能夠經過私鑰進行解密。ide

1.在命令行下經過openssl指令得到證書ui

//生成長度爲 1024 的私鑰:private_key.pem (文件名可自定義)
openssl genrsa -out private_key.pem 1024

//使用私鑰文件建立所需的證書:rsaCertReq.csr(文件名可自定義)
openssl req -new -key private_key.pem -out rsaCertReq.csr

//使用 x509 建立證書:rsaCert.crt(文件名可自定義)
openssl x509 -req -days 3650 -in rsaCertReq.csr -signkey private_key.pem -out rsaCert.crt

//生成 .der 格式的公鑰:public_key.der(文件名可自定義)
openssl x509 -outform der -in rsaCert.crt -out public_key.der

//生成解密所需 .p12文件:private_key.p12(文件名可自定義)
openssl pkcs12 -export -out private_key.p12 -inkey private_key.pem -in rsaCert.crt

在命令行種可能須要你的一些信息去生成公鑰和私鑰加密

Country Name (2 letter code) [AU]:CN                                              // 國家碼lua

State or Province Name (full name) [Some-State]:china                     //地區碼spa

Locality Name (eg, city) []:wuhan                   // 本地碼

Organization Name (eg, company) [Internet Widgits Pty Ltd]:airway   // 公司名稱

Organizational Unit Name (eg, section) []:airway                               // 部門

Common Name (eg, YOUR name) []:airway                                       // 名字

Email Address []:                            //郵箱

注意:在生成密鑰對的時候須要填入 私鑰的提取密碼,請記住,解密的時候須要用到。

 

2.咱們須要完善咱們的代碼來實現RSA加密和解密

經過在命令行中的操做,咱們最後能夠獲得咱們須要的公鑰和私鑰文件。

static SecKeyRef _public_key = nil;
        // 從公鑰證書文件中獲取到公鑰的SecKeyRef指針:  @"public_key" ofType:@"der"
        NSString *publicKeyPath = [paramsDict stringValueForKey:@"publicKey" defaultValue:@""];
        publicKeyPath = [self getPathWithUZSchemeURL:publicKeyPath];
        if (![[NSFileManager defaultManager] fileExistsAtPath:publicKeyPath]) {
            [self sendResultEventWithCallbackId:rsaCbId dataDict:@{@"status":[NSNumber numberWithBool:false]} errDict:@{@"code":@(-1)} doDelete:NO];
            return;
        }
        NSData *certificateData = [[NSData alloc]initWithContentsOfFile:publicKeyPath];
        SecCertificateRef myCertificate =  SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certificateData);
        SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
        SecTrustRef myTrust;
        OSStatus status = SecTrustCreateWithCertificates(myCertificate,myPolicy,&myTrust);
        SecTrustResultType trustResult;
        if (status == noErr) {
            status = SecTrustEvaluate(myTrust, &trustResult);
        }
        _public_key = SecTrustCopyPublicKey(myTrust);
        CFRelease(myCertificate);
        CFRelease(myPolicy);
        CFRelease(myTrust);

        SecKeyRef key = _public_key;
        size_t cipherBufferSize = SecKeyGetBlockSize(key);
        uint8_t *cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
        NSData *stringBytes = [inString dataUsingEncoding:NSUTF8StringEncoding];
        size_t blockSize = cipherBufferSize - 11;
        size_t blockCount = (size_t)ceil([stringBytes length] / (double)blockSize);
        NSMutableData *encryptedData = [[NSMutableData alloc] init];
        NSString *outString = [[NSString alloc] init];
        for (int i=0; i<blockCount; i++) {
            int bufferSize = MIN(blockSize,[stringBytes length] - i * blockSize);
            NSData *buffer = [stringBytes 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{
                outString = @"";
            }
        }
        if (cipherBuffer) {
            free(cipherBuffer);
        }
        outString = [encryptedData base64Encoding];
}
return outString;
NSString *password = [paramsDict stringValueForKey:@"password" defaultValue:@""];
    NSString *inString = [paramsDict stringValueForKey:@"data" defaultValue:@""];
    NSString *value = @"";
    if (inString.length <= 0) {
        //err:1
        return value;
    } else {
        // 從私鑰證書文件中獲取到公鑰的SecKeyRef指針:  @"private_key" ofType:@"pem"
        NSString *privateKeyPath = [paramsDict stringValueForKey:@"privateKey" defaultValue:@""];
        privateKeyPath = [self getPathWithUZSchemeURL:privateKeyPath];
        if (![[NSFileManager defaultManager] fileExistsAtPath:privateKeyPath]) {
            return value;
        }
        NSData *p12Data = [[NSData alloc]initWithContentsOfFile:privateKeyPath];
        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;
            }
        } else {
            return value;
        }
        CFRelease(items);
        
        NSData *cipherData = [NSData dataWithBase64EncodedString:inString];
        //        NSData* decryptData = [self rsaDecryptData: data];
        size_t cipherLen = [cipherData length];
        void *cipher = malloc(cipherLen);
        [cipherData getBytes:cipher length:cipherLen];
        size_t plainLen = SecKeyGetBlockSize(privateKeyRef) - 12;
        void *plain = malloc(plainLen);
        OSStatus status = SecKeyDecrypt(privateKeyRef, kSecPaddingPKCS1, cipher, cipherLen, plain, &plainLen);
        if (status != noErr) {
            return value;
        }
        NSData *decryptedData = [[NSData alloc] initWithBytes:(const void *)plain length:plainLen];
        value = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
        NSMutableString *outString = [[NSMutableString alloc] init];
        //若是沒有進行加密直接解密,outString 將爲 nil
        if (!value && decryptedData && decryptedData.length > 0) {
            Byte *datas = (Byte*)[decryptedData bytes];
            outString = [NSMutableString stringWithCapacity:decryptedData.length * 2];
            for(int i = 0; i < decryptedData.length; i++){
                [outString appendFormat:@"%02x", datas[i]];
            }
            value = [outString copy];
        }
        return value;
    }
相關文章
相關標籤/搜索