CCCrypt Entschlüsselung in AES-CBC funktioniert auch ohne IV
Ich habe ein verwirrendes problem, wo der Entschlüsselung einer Datei die verschlüsselt wurde, mit CCCrypt ist AES-CBC-Modus mit einer randomisierten, 16byte IV produziert, die genau die gleiche Ausgabe, ob ich den pass in der gleichen korrekten IV verwendet für die Verschlüsselung oder gar keine.
Was ich erwarte: mit einem NULL-IV zum entschlüsseln sollte nicht dazu führen, eine korrekte Entschlüsselung.
Was ich beobachten: mit einem NULL-IV resultiert in das gleiche Ergebnis wie mit der IV für die Verschlüsselung verwendet.
Unten der Vollständigkeit halber, hier ist der wichtige code-Schnipsel, iv
übergeben wird als 16-byte-sicher randomisierte NSData.
Was bin ich nicht zu verstehen hier? Ist CCCrypt irgendwie herauszufinden, die IV, die aus den verschlüsselten Daten selbst? Ich konnte nicht finden, dass irgendetwas um, dass in den docs.
- (NSData *)encryptedDataForData:(NSData *)rawData
withKey:(NSData *)key
iv:(NSData *)iv
error:(NSError __autoreleasing**)error
{
size_t outLength;
NSMutableData *cipherData = [NSMutableData dataWithLength:rawData.length + kAlgorithmBlockSize];
CCCryptorStatus result = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCModeCBC,
key.bytes,
key.length,
iv.bytes,
rawData.bytes,
rawData.length,
cipherData.mutableBytes,
cipherData.length,
&outLength);
if (result == kCCSuccess) {
cipherData.length = outLength;
return cipherData;
} else {
return nil;
}
}
- (NSData *)decryptedDataForData:(NSData *)encryptedData withKey:(NSData *)key error:(NSError __autoreleasing**)error
{
size_t outLength;
NSMutableData *decryptedData = [NSMutableData dataWithLength:encryptedData.length];
//this line is just to illustrate how setting the exact same iv here - if this one
//was used for encryption - results in same output as when passing iv = NULL
NSData *iv = [Cryptor dataForHex:@"724a7fc0 0d8ac9d5 f09ff4c1 64d2d1bb"];
CCCryptorStatus result = CCCrypt(kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCModeCBC,
key.bytes,
key.length,
iv.bytes, //iv OR NULL --> same result o_O
encryptedData.bytes,
encryptedData.length,
decryptedData.mutableBytes,
decryptedData.length,
&outLength);
if (result == kCCSuccess) {
decryptedData.length = outLength;
return decryptedData;
} else {
return nil;
}
}
EDIT:
Deutlich, egal, die IV, die ich für die Entschlüsselung (ausprobiert eine Reihe von verschiedenen randomisierten IV), habe ich immer bekommen, byte für byte identische Ergebnisse. Selbst wenn ich die entschlüsseln nur einen partiellen Teil der verschlüsselten Datei irgendwo aus der Mitte der verschlüsselten Datei.
Ist dies vielleicht im Zusammenhang zu den eigentlichen Daten, ich bin en/Entschlüsselung (mp3-Dateien)?
Wenn ich einfach einige beliebige Stück die eigentliche verschlüsselte Datei, die der decryptor, sollte es nicht erforderlich den block Recht vor, die chunk-Daten (die ich nicht bieten explizit als IV), um die richtige Entschlüsselung? Die einzige Erklärung, die ich denken konnte, hier persönlich ist, dass CCCrypt nur verwendet immer die ersten 16 Byte als IV und nicht entschlüsseln, diese fällt aber in der Ausgabe.
EDIT 2:
Ausgabe der en - /decryption, zeigen die ersten beiden Blöcke von in-und output-Daten, der Schlüssel und der iv:
# encryption
data <4cd9b050 30c04bf9 2a0cb024 19010a31 400c2261 0069196a d77bcae6 9799ae26>
iv <724a7fc0 0d8ac9d5 f09ff4c1 64d2d1bb>
key <78656a1a 337fddd6 fa52e34d 9156d187>
encrypted <cf85cdbe 10a87309 a6fb4c4e ce640619 8f445b70 3738018a e78291a7 b4ea26ce>
# decryption with correct IV
data <cf85cdbe 10a87309 a6fb4c4e ce640619 8f445b70 3738018a e78291a7 b4ea26ce>
iv <724a7fc0 0d8ac9d5 f09ff4c1 64d2d1bb>
key <78656a1a 337fddd6 fa52e34d 9156d187>
decrypted <4cd9b050 30c04bf9 2a0cb024 19010a31 400c2261 0069196a d77bcae6 9799ae26>
# decryption with zero IV
data <cf85cdbe 10a87309 a6fb4c4e ce640619 8f445b70 3738018a e78291a7 b4ea26ce>
iv <00000000 00000000 00000000 00000000>
key <78656a1a 337fddd6 fa52e34d 9156d187>
decrypted <4cd9b050 30c04bf9 2a0cb024 19010a31 400c2261 0069196a d77bcae6 9799ae26>
# decryption with different IV
data <cf85cdbe 10a87309 a6fb4c4e ce640619 8f445b70 3738018a e78291a7 b4ea26ce>
iv <12345678 9abcdef1 23456789 abcdef12>
key <78656a1a 337fddd6 fa52e34d 9156d187>
decrypted <4cd9b050 30c04bf9 2a0cb024 19010a31 400c2261 0069196a d77bcae6 9799ae26>
EDIT 3:
Den code für -dataForHex:
ist:
+ (NSData *)dataForHex:(NSString *)hex
{
NSString *hexNoSpaces = [[[hex stringByReplacingOccurrencesOfString:@" " withString:@""]
stringByReplacingOccurrencesOfString:@"<" withString:@""]
stringByReplacingOccurrencesOfString:@">" withString:@""];
NSMutableData *data = [[NSMutableData alloc] init];
unsigned char whole_byte = 0;
char byte_chars[3] = {'\0','\0','\0'};
for (NSUInteger i = 0; i < [hexNoSpaces length] / 2; i++) {
byte_chars[0] = (unsigned char) [hexNoSpaces characterAtIndex:(NSUInteger) (i * 2)];
byte_chars[1] = (unsigned char) [hexNoSpaces characterAtIndex:(NSUInteger) (i * 2 + 1)];
whole_byte = (unsigned char)strtol(byte_chars, NULL, 16);
[data appendBytes:&whole_byte length:1];
}
return data;
}
- Beachten Sie, dass "Wenn der CBC-Modus ausgewählt ist und keine IV vorgesehen ist, eine IV-alle Nullen verwendet werden." Also, wenn Sie vergleichen mit einer IV von alle null, mit NULL, dann würden Sie erwarten, das gleiche Ergebnis. Wenn Sie wollen bessere Antworten, bitte zeigen Sie Probe IV und Entschlüsselung Ergebnisse in hexadezimal.
- Ich habe Beispiel-Ausgänge (die ersten beiden Blöcke) vom verschlüsseln und entschlüsseln von meiner Beispiel-Datei. Es zeigt die Schlüssel, iv und Daten, wie Sie sind übergeben in / aus CCCrypt mit dem code oben.
- Es scheint, dass die iv nicht verwendet wird. Mit der iv auf die verschlüsselten Daten:
d2c2efee 54e43781 549eec03 9db688e1 7c4248e7 e2ac1d80 7105ffae 4043ffb3
. Dies ist mit meinem test-code, siehe neue Antwort. - Wo ist der code für
Cryptor dataForHex
? CCCrypt
ist eine einfache Funktion mit nur wenigen input-Parametern, es ist keine Magie, es ist wissen zu arbeiten. Wenn es liefert nicht die richtigen Ergebnisse der input-Parameter sind nicht korrekt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Verwendet für die Formatierung Kommentar.
Iv:
Iv 0 s:
Es ist klar, dass die iv nicht verwendet wird, in den OP-code.
Code für oben:
dataForHex:
. Meine CCCrypt code sieht im Grunde genau wie die Eure, und wenn ich drucken Sie die IV NSData durch diese erzeugten helper-Methode, die es drucken genau die Ausgabe, die ich erwarten würde. Non-zero-hex-Werte genau so, wie Sie waren.kCCModeCBC
. Ich verstehe, dass CBC-Standard ist, aber ich wollte explizit für Dokumentations-Zwecke. AllerdingskCCModeCBC
(mit Wert 2), ist nicht von einerCCOptions
aber einCCMode
. UndCCMode
Wert 2 passiert gleichkCCOptionECBMode
imCCOptions
... Also ich war versehentlich einschalten ECB-Modus, wenn ich nur wollte explizit sein. Danke!CCCrypt
hatCCOptions options
die keine CBC-Modus-option ist die Standardeinstellung.CCCryptorCreateWithMode
hatCCMode
umfasstkCCModeCBC
. Lesen Sie die Dokumentation Apple Man-Pages ist immer eine option—als ein Fehlschlag.Es ist auch darauf hinzuweisen, dass man nie im Modus mit der Polsterung Optionen. Ich habe gesehen, dass dieses um einiges, und ich habe tatsächlich fallen in die gleiche Falle, die versuchen, eine "explizite wie möglich".
Werden sollte:
Fun fact 1: Beide
kCCModeEBC
undkCCOptionPKCS7Padding
teilen den gleichen Wert: 1, und würde tatsächlich bewerten der VerwendungkCCOptionPKCS7Padding
, welche dann standardmäßig aufkCCModeCBC
.Fun fact 2: Mit
kCCOptionPKCS7Padding | kCCModeCBC
wertet sowohlkCCOptionPKCS7Padding
Flagge undkCCOptionECBMode
eingestellt werden, die tatsächlich Ergebnisse inkCCModeEBC
verwendet wird.kCCOptionPKCS7Padding
gibt mir zusätzliche Zeichen, die auf PHP. Ich habe bereits Hinzugefügtpkcs7_unpad
. (Entschlüsselung), aber noch immer zusätzliche Zeichen am Anfang.Die iv ist nur für den ersten block bei der Entschlüsselung, weitere Blöcke verwenden, die cipher text aus dem vorherigen block so ist es etwas selbst zu synchronisieren.
Wikipedia Bild:
Aus Wikipedia Block cipher mode of operation.
So, Kommissionierung bis die Entschlüsselung in der Mitte von einem CBC-verschlüsselten stream auf einem block boundary funktioniert, außer für den ersten block.
NSLog(@"iv: %@", iv);
vermute ich:Cryptor dataForHex:
. Fügen Sie zu der Frage ein Beispiel, das zeigt diese darunter: encryptedData (die ersten beiden Blöcke ist in Ordnung), key, iv und decryptedData (die ersten beiden Blöcke ist in Ordnung) im hex-dump format.Lesen Sie die richtige Antwort hier:
http://www.remote-exploit.org/archives/2012/01/09/the_apple_idioten_vektor_iv/
Apple einen Fehler in der Krypto-Bibliothek, die meint, dass, wenn der IV-Vektor wird nicht vorausgesetzt, Sie stellen automatisch die IV zu einem null-Vektor zurückgegeben wird, sondern ein Fehler. Ein IV sollte immer vorhanden sein, um sicherzustellen, dass die beste Sicherheit und Apple nicht tun sollte Ihre null-Annahme, da es sehr stark schwächt Sicherheit und macht es anfällig für Angriffe.