先貼出代碼的地址,作個說明,由於RSA加密在iOS的代碼比較少,網上開源的也不多,最多的才8個星星。使用過程當中發現有錯誤。而後我作了修正,和另外一個庫進行了整合,而後將其支持CocoaPod。html
https://github.com/qianhongqiang/RSAEncryptor
RSA加密的原理就不拾人牙慧了,一搜一大堆。不過在這裏仍是要感嘆下數學的魅力。git
在這裏對代碼的一些細節進行一下分析,github
- (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++) { NSInteger bufferSize = 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; }
這裏是加密的邏輯,根據RSA的原理,cipherBufferSize是祕鑰長度/8,也就是祕鑰的字節數,加密的長度不能超過祕鑰的長度,因此加密須要分段。舉個例子,你加密的長度是300個字節,你的祕鑰是1024位(128字節)的,那麼你須要分紅3段去加密,前面兩段是128,最後一段是44個字節。可是這個加密塊大小不能直接這麼設置,須要有一塊用於填充加密信息的,RSA_PKCS1_PADDING,具體的能夠參見這片博文app
http://www.cnblogs.com/spencerN/archive/2012/10/18/2729602.html
因此不管你的祕鑰長度是多少,都須要保留11個字節用於PKCS1填充。這也就是代碼中出現了-11的緣由。kSecPaddingPKCS1在這裏會被用到
SecKeyEncrypt(key, kSecPaddingPKCS1, (const uint8_t *)[buffer bytes], [buffer length], cipherBuffer, &cipherBufferSize);分段加密出來的結果是祕鑰的長度,會比加密前長出11個字節
分段加密的結果拼接後得到最終的加密結果。
解密也是同樣的流程,不過不要設置RSA_PKCS1_PADDING,只須要按照祕鑰的長度去獲取,流程與加密幾乎一致。在我最初的代碼中,原做者沒有分段揭祕,我修正了這個問題。ui