iOS中RSA加密详解

先贴出代码的地址,作个说明,由于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

相关文章
相关标签/搜索