我正在尝试使用 SecKeyEncrypt 函数使用 PKCS1 填充实现 RSA 加密。
代码如下:
NSData *encryptText(NSString *text, SecKeyRef publicKey)
{
    NSCParameterAssert(text.length > 0);
    NSCParameterAssert(publicKey != NULL);
    NSData *dataToEncrypt = [text dataUsingEncoding:NSUTF8StringEncoding];
    const uint8_t *bytesToEncrypt = dataToEncrypt.bytes;
    size_t cipherBufferSize = SecKeyGetBlockSize(publicKey);
    NSCAssert(cipherBufferSize > 11, @"block size is too small: %zd", cipherBufferSize);
    const size_t inputBlockSize = cipherBufferSize - 11; // since we'll use PKCS1 padding
    uint8_t *cipherBuffer = (uint8_t *) malloc(sizeof(uint8_t) * cipherBufferSize);
    NSMutableData *accumulator = [[NSMutableData alloc] init];
    @try {
        for (size_t block = 0; block * inputBlockSize < dataToEncrypt.length; block++) {
            size_t blockOffset = block * inputBlockSize;
            const uint8_t *chunkToEncrypt = (bytesToEncrypt + block * inputBlockSize);
            const size_t remainingSize = dataToEncrypt.length - blockOffset;
            const size_t subsize = remainingSize < inputBlockSize ? remainingSize : inputBlockSize;
            size_t actualOutputSize = cipherBufferSize;
            OSStatus status = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, chunkToEncrypt, subsize, cipherBuffer, &actualOutputSize);
            if (status != noErr) {
                NSLog(@"Cannot encrypt data, last SecKeyEncrypt status: %ld", status);
                return nil;
            }
            [accumulator appendBytes:cipherBuffer length:actualOutputSize];
        }
        return [accumulator copy];
    }
    @finally {
        free(cipherBuffer);
    }
}
它在 iOS 6 上完美运行,但在 iOS 5 上失败,SecKeyEncrypt 返回-50( errSecParam)。如果我将 11 更改为 12 ,它将在 iOS 5 上运行inputBlockSize = cipherBufferSize - 11。SecKeyGetBlockSize() - 11苹果文档说如果使用 PKCS1 填充,输入块长度应该小于或等于。但在 iOS 5 上,它肯定需要更短的输入。
根据文档,我的密钥块大小为 64,因此输入块的最大长度为 53。在 iOS 5 上,只有 52 或更少可以工作。
这段代码有什么问题?还是 iOS 5 Security.framework 错误?
UPD:问题仅使用 512 位密钥重现。尝试使用生成的 1024 位密钥,代码适用于 iOS 511