iOS常用加密之RSA加密解密

來源:互聯網
上載者:User

標籤:pad   get   idg   使用   idt   根據   malloc   images   table   

前言:

iOS常用的加密有很多種,前兩天在工作中遇到了RSA加密,現在把代嗎分享出來。

RSA基本原理

RSA使用"秘匙對"對資料進行加密解密.在加密解密資料前,需要先產生公開金鑰(public key)和私密金鑰(private key).

  • 公開金鑰(public key): 用於加密資料. 用於公開, 一般存放在資料提供方, 例如iOS用戶端.
  • 私密金鑰(private key): 用於解密資料. 必須保密, 私密金鑰泄露會造成安全問題
第一步:公開金鑰、私密金鑰的產生

iOS開發人員可直接在Mac終端產生,命令如下,產生公開金鑰der檔案的時候需要填寫國家地區等基本資料,也可直接忽略不填。產生私p12檔案的時候需要填寫密碼,這個必填而且要記住,後面會用得著。

// 產生1024位私密金鑰
openssl genrsa -out private_key.pem 1024
// 根據私密金鑰產生CSR檔案
openssl req -new -key private_key.pem -out rsaCertReq.csr
// 根據私密金鑰和CSR檔案產生crt檔案
openssl x509 -req -days 3650 -in rsaCertReq.csr -signkey private_key.pem -out rsaCert.crt

// 為IOS端產生公開金鑰der檔案
openssl x509 -outform der -in rsaCert.crt -out public_key.der

// 將私密金鑰匯出為這p12檔案
openssl pkcs12 -export -out private_key.p12 -inkey private_key.pem -in rsaCert.crt

第二步:加密相關的代碼

在加密加密的時候需要定義公有變數公開金鑰和私密金鑰

    SecKeyRef _publicKey;    SecKeyRef _privateKey;
加密相關的代碼
 1 #pragma mark - 加密相關 2 //用本地認證載入公開金鑰 3 - (void)loadPublicKeyWithPath:(NSString *)derFilePath 4 { 5     NSData *derData = [[NSData alloc] initWithContentsOfFile:derFilePath]; 6     if (derData.length > 0) 7     { 8         [self loadPublicKeyWithData:derData]; 9     }10     else11     {12         NSLog(@"load public key fail with path: %@", derFilePath);13     }14 }15 //載入公開金鑰方法16 - (void)loadPublicKeyWithData:(NSData *)derData17 {18     SecCertificateRef myCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)derData);19     SecPolicyRef myPolicy = SecPolicyCreateBasicX509();20     SecTrustRef myTrust;21     OSStatus status = SecTrustCreateWithCertificates(myCertificate,myPolicy,&myTrust);22     SecTrustResultType trustResult;23     if (status == noErr) {24         status = SecTrustEvaluate(myTrust, &trustResult);25     }26     27     SecKeyRef securityKey = SecTrustCopyPublicKey(myTrust);  CFRelease(myCertificate);  CFRelease(myPolicy);  CFRelease(myTrust);28     29     _publicKey = securityKey;30 }31 32 33 //將常值內容加密34 - (NSString *)rsaEncryptText:(NSString *)text35 {36     NSData *encryptedData = [self rsaEncryptData:[text dataUsingEncoding:NSUTF8StringEncoding]];37     NSString *base64EncryptedString = [encryptedData base64EncodedStringWithOptions:0];38     return base64EncryptedString;39 }40 41 42 //分段再加密資料43 - (NSData *)rsaEncryptData:(NSData *)data44 {45     SecKeyRef key = _publicKey;46     47     size_t cipherBufferSize = SecKeyGetBlockSize(key);48     uint8_t *cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));49     size_t blockSize = cipherBufferSize - 11;50     size_t blockCount = (size_t)ceil([data length] / (double)blockSize);51     NSMutableData *encryptedData = [[NSMutableData alloc] init] ;52     for (int i = 0; i < blockCount; i++)53     {54         size_t bufferSize = MIN(blockSize,[data length] - i * blockSize);55         NSData *buffer = [data subdataWithRange:NSMakeRange(i * blockSize, bufferSize)];56         OSStatus status = SecKeyEncrypt(key, kSecPaddingPKCS1,(const uint8_t *)[buffer bytes],[buffer length],cipherBuffer,&cipherBufferSize);57         if (status == noErr)58         {59             NSData *encryptedBytes = [[NSData alloc] initWithBytes:(const void *)cipherBuffer length: cipherBufferSize];60             [encryptedData appendData:encryptedBytes];61         }62         else63         {64             if (cipherBuffer) {65                 free(cipherBuffer);66             }      return nil;67         }68         69     }70     if (cipherBuffer)71     {72         free(cipherBuffer);73         74     }75     return encryptedData;76 }
第三步:解密相關代碼
#pragma mark - 解密相關- (void)loadPrivateKeyWithPath:(NSString *)p12FilePath password:(NSString *)p12Password{    NSData *data = [NSData dataWithContentsOfFile:p12FilePath];    if (data.length > 0)    {        [self loadPrivateKeyWithData:data password:p12Password];}    else    {    NSLog(@"load private key fail with path: %@", p12FilePath);}}//產生私密金鑰- (void)loadPrivateKeyWithData:(NSData *)p12Data password:(NSString *)p12Password{    SecKeyRef privateKeyRef = NULL;    NSMutableDictionary * options = [[NSMutableDictionary alloc] init];        [options setObject:p12Password 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;        }    }        _privateKey = privateKeyRef;    CFRelease(items);}//調用下面方法進行解密,最後返回一個字串- (NSString *)rsaDecryptText:(NSString *)text{    NSData *data = [[NSData alloc] initWithBase64EncodedString:text options:0];    NSData *decryptData = [self rsaDecryptData:data];    NSString *result = [[NSString alloc] initWithData:decryptData encoding:NSUTF8StringEncoding];    return result;}//用私密金鑰解密的方法,被上面方法調用- (NSData *)rsaDecryptData:(NSData *)data{    SecKeyRef key = _privateKey;        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;}
第四步:RSA加密解密的應用

在加密活解密之前一定要閑載入認證,然後再調用加密方法,直接上代碼

 1 - (IBAction)decryptionBtnClick:(id)sender { 2      3     NSString *path = [[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"]; 4     [self loadPublicKeyWithPath:path]; 5     path = [[NSBundle mainBundle] pathForResource:@"private_key" ofType:@"p12"]; 6     [self loadPrivateKeyWithPath:path password:@"bestnet"]; 7      8     NSString *encryptStr = self.encryptTextFeild.text; 9     if (encryptStr.length > 0)10     {11         NSString *miwen = [self rsaEncryptText:encryptStr];12         self.miWenLabel.text = [NSString stringWithFormat:@"加密結果:%@", miwen];13         if (miwen.length > 0)14         {15             self.decryptionTextFeild.text = [self rsaDecryptText:miwen];16         }17     }18 }

 

 

iOS常用加密之RSA加密解密

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.