iPhone --- 3DES Encryption возвращает "неправильные" результаты?
У меня есть серьезные проблемы с функцией CommonCrypto. Существует два существующих приложения для BlackBerry и Windows Mobile, оба используют шифрование Triple-DES с режимом ECB для обмена данными. На обоих зашифрованные результаты одинаковы.
Теперь я хочу внедрить шифрование 3DES в наше приложение для iPhone, поэтому я выбрал CommonCrypto: http://www.opensource.apple.com/source/CommonCrypto/CommonCrypto-32207/CommonCrypto/CommonCryptor.h
Я получаю некоторые результаты, если использую режим CBC, но они не соответствуют результатам Java или C#. В любом случае, я хочу использовать режим ECB, но у меня это не работает вообще - появляется ошибка параметра...
Это мой призыв к режиму ЕЦБ... Я немного его обрезал:
const void *vplainText;
plainTextBufferSize = [@"Hello World!" length];
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
plainText = (const void *) [@"Hello World!" UTF8String];
NSString *key = @"abcdeabcdeabcdeabcdeabcd";
ccStatus = CCCrypt(kCCEncrypt,
kCCAlgorithm3DES,
kCCOptionECBMode,
key,
kCCKeySize3DES,
nil, // iv, not used with ECB
plainText,
plainTextBufferSize,
(void *)bufferPtr, // output
bufferPtrSize,
&movedBytes);
Это более или менее код здесь: http://discussions.apple.com/thread.jspa?messageID=9017515 Но, как уже упоминалось, я получаю ошибку параметра каждый раз...
Когда я использую kCCOptionPKCS7Padding вместо kCCOptionECBMode и устанавливаю один и тот же вектор инициализации в C# и коде моего iPhone, iPhone дает мне разные результаты. Есть ли ошибка, получая мой вывод из bufferPtr? В настоящее время я получаю зашифрованные данные таким образом:
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result = [[NSString alloc] initWithData:myData encoding:NSISOLatin1StringEncoding];
Кажется, я почти перепробовал каждую настройку дважды, разные кодировки и так далее... где моя ошибка?
3 ответа
Я считаю, что проблема в том, что одного kCCOptionECBMode недостаточно. Вам также нужно заполнение (так как это блочный шифр). Если вы передадите оба (т.е. kCCOptionPKCS7Padding | kCCOptionECBMode), это сработает.
Можете ли вы опубликовать сообщение об ошибке?
Я обнаружил, что один из лучших способов устранения неполадок - это взять известный ввод, известный ключ и известный вывод (" тестовые векторы") и сравнить байты ожидаемого вывода с наблюдаемым выводом.
То, что вы делаете здесь, вероятно, не очень хороший способ проверить вывод:
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result = [[NSString alloc] initWithData:myData encoding:NSISOLatin1StringEncoding];
Как вы знаете, зашифрованные двоичные данные могут быть интерпретированы с NSISOLatin1StringEncoding
кодирование?
Вместо этого сравните байты напрямую (через [myData description]
или тому подобное) или перевести вывод в шестнадцатеричное или base64 кодирование.
Я понимаю, что это старый вопрос, но для справки, я думаю, что ваш ключ не должен передаваться как NSString. Вместо этого ключ должен быть преобразован из шестнадцатеричного в байтовый массив. Это расширение hexToBytes NSString должно обеспечить то, что вам нужно, выполнив следующие действия:
[[key hexToBytes] bytes]
Ключ также должен быть вдвое длиннее указанного (48 символов в шестнадцатеричном формате, т.е. 24 байта).