2013-01-09 4 views
5

Ich verwende SecKeyEncrypt mit einem JSON-formatierten String als Eingabe. Wenn SecKeyEncrypt eine plainTextLength von weniger als 246 übergeben, funktioniert es. Wenn ich eine Länge von 246 oder mehr übergebe, schlägt es mit dem Rückgabewert fehl: paramErr (-50).Warum würde SecKeyEncrypt paramErr (-50) für Eingabezeichenfolgen mit mehr als 246 Byte zurückgeben?

Es könnte eine Frage der Zeichenfolge selbst sein. Ein Beispiel dafür, was ich SecKeyEncrypt senden könnte, ist:

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

Der 245. Charakter ist ‚0‘.

Die einzige Eingabe, die zwischen dieser Arbeit ändert und ist die plainTextLength. SecKeyGetBlockSize() gibt 256 an mich zurück, daher sollte jede Eingabe mit bis zu 256 Zeichen funktionieren.

Hier ist meine encrypt Methode:

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

Antwort

7

Aus der Dokumentation:

plainTextLen
Länge in Bytes der Daten in dem unverschlüsselten Text Puffer. Dieser Wert muss kleiner oder gleich dem von der SecKeyGetBlockSize-Funktion zurückgegebenen Wert sein. Wenn die PKCS1-Auffüllung ausgeführt wird, ist die maximale Länge der Daten, die verschlüsselt werden können, um 11 Byte kleiner als der Wert, der von der SecKeyGetBlockSize-Funktion (secKeyGetBlockSize() - 11) zurückgegeben wird.

(Hervorhebung von mir)

Sie verwenden PKCS1 Polsterung. Wenn also die Blockgröße 256 ist, können Sie nur bis zu 245 Bytes gleichzeitig verschlüsseln.

+0

Ja. Duh. Vielen Dank! – Mathew

Verwandte Themen