2013-01-09 5 views
5

Używam SecKeyEncrypt z ciągiem sformatowanym JSON jako danych wejściowych. Jeśli przejdzie SecKeyEncrypt plainTextLength mniej niż 246, to działa. Jeśli przekażę mu długość 246 lub więcej, nie powiedzie się z wartością zwracaną: paramErr (-50).Dlaczego SecKeyEncrypt zwraca paramErr (-50) dla ciągów wejściowych dłuższych niż 246 bajtów?

Może to być kwestia samej struny. Przykładem tego, co mogę wysłać SecKeyEncrypt jest:

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

245-cie postać jest „0”.

TYLKO dane wejściowe, które zmieniają się między tymi roboczymi a zwykłymi długościami tekstu. SecKeyGetBlockSize() zwraca mi 256, więc wszelkie dane wejściowe o maksymalnej długości 256 znaków powinny działać.

Oto moja metoda szyfrowania:

 
+ (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; 
} 

Odpowiedz

7

Z dokumentacji:

plainTextLen
Długość w bajtach danych w buforze tekstu jawnego. Musi być mniejszy lub równy wartości zwróconej przez funkcję SecKeyGetBlockSize. Podczas wykonywania wypełniania PKCS1 maksymalna długość danych, które można zaszyfrować, jest o 11 bajtów mniejsza niż wartość zwracana przez funkcję SecKeyGetBlockSize (secKeyGetBlockSize() - 11).

(Kopalnia nacisk)

Używasz PKCS1 wyściółkę. Jeśli więc rozmiar bloku wynosi 256, możesz zaszyfrować maksymalnie 245 bajtów naraz.

+0

Tak. Duh. Dzięki! – Mathew