ios – 为什么SecKeyEncrypt会为超过246字节的输入字符串返回paramErr(-50)?

前端之家收集整理的这篇文章主要介绍了ios – 为什么SecKeyEncrypt会为超过246字节的输入字符串返回paramErr(-50)?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我使用SecKeyEncrypt和 JSON格式的字符串作为输入.如果通过SecKeyEncrypt的plainTextLength小于246,它可以工作.如果我传递的长度为246或更多,则失败并返回值:paramErr(-50).

它可能是字符串本身的问题.我可能发送SecKeyEncrypt的一个例子是:

{"handle":"music-list","sym_key":"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALeaEO7ZrjgOFGLBzBHZtQuzH2GNDYMLWP+fIFNu5Y+59C6HECY+jt0yOXXom2mzp/WYYI/9G+Ig8OD6YiKv2nMCAwEAAQ==","app_id":"xgfdt.LibraryTestApp","api_key":"7e080f74de3625b90dd293fc8be560a5cdfafc08"}

第245个字符为’0′.

在此工作之间切换的唯一输入是plainTextLength. SecKeyGetBlockSize()返回256给我,所以任何长达256个字符的输入都应该有效.

这是我的加密方法

+ (NSData*)encrypt:(NSString*)data usingPublicKeyWithTag:(NSString*)tag
{

    OSStatus status = noErr;

    size_t cipherBufferSize;
    uint8_t *cipherBuffer;

    // [cipherBufferSize]
    size_t dataSize = 246;//[data lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    const uint8_t* textData = [[data dataUsingEncoding:NSUTF8StringEncoding] bytes];

    SecKeyRef publicKey = [Encryption copyPublicKeyForTag:tag];

    NSAssert(publicKey,@"The public key being referenced by tag must have been stored in the keychain before attempting to encrypt data using it!");

    //  Allocate a buffer

    cipherBufferSize = SecKeyGetBlockSize(publicKey);
    // this value will not get modified,whereas cipherBufferSize may.
    const size_t fullCipherBufferSize = cipherBufferSize;
    cipherBuffer = malloc(cipherBufferSize);

    NSMutableData* accumulatedEncryptedData = [NSMutableData dataWithCapacity:0];

    //  Error handling

    for (int ii = 0; ii*fullCipherBufferSize < dataSize; ii++) {
        const uint8_t* dataToEncrypt = (textData+(ii*fullCipherBufferSize));
        const size_t subsize = (((ii+1)*fullCipherBufferSize) > dataSize) ? fullCipherBufferSize-(((ii+1)*fullCipherBufferSize) - dataSize) : fullCipherBufferSize;

        // Encrypt using the public key.
        status = SecKeyEncrypt(    publicKey,kSecPaddingPKCS1,dataToEncrypt,subsize,cipherBuffer,&cipherBufferSize
                               );

        [accumulatedEncryptedData appendBytes:cipherBuffer length:cipherBufferSize];
    }

    if (publicKey) CFRelease(publicKey);

    free(cipherBuffer);

    return accumulatedEncryptedData;
}

解决方法

从文档:

plainTextLen
Length in bytes of the data in the plainText buffer. This must be less than or equal to the value returned by the SecKeyGetBlockSize function. When PKCS1 padding is performed,the maximum length of data that can be encrypted is 11 bytes less than the value returned by the SecKeyGetBlockSize function (secKeyGetBlockSize() – 11).

(强调我的)

您正在使用PKCS1填充.因此,如果块大小为256,则一次最多只能加密245个字节.

猜你在找的iOS相关文章