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 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...