Android -> Миграция iOS-шифра - PullRequest
2 голосов
/ 06 октября 2011

Мне нужно перенести приложение Android на iOS, которая использует Cipher.Итак, вот код Android:

PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESedeEngine()));
...
byte[] result = Hex.encode(output, 0, output.length);
String resultS = new String(Str.toChars(result));

Я много чего пробовал для target-c, но не могу найти способ получить ту же строку, что и на Java.Я использовал здесь код iOS http://dotmac.rationalmind.net/2009/02/aes-interoperability-between-net-and-iphone/ (и многое другое, но все делают одно и то же).

А затем, чтобы получить строку в iOS, используйте что-то вроде:

NSString* resultS = [encryptedData base64Encoding]

но строки результата не совпадают.Может быть, проблема в том, как я обрабатываю кодировку для NSData (кажется, что версия Java не использует base64, я в порядке?)

Есть идеи?

РЕДАКТИРОВАТЬ 1:

Хорошо, я добился определенного прогресса (надеюсь).При проверке кода Java они используют размер блока 8 и DES / CBC с ключом из 24 символов.Поэтому я изменяю код с CocoaFu на этот:

- (NSData *)doCipher:(NSData *)dataIn
             key:(NSData *)symmetricKey
         context:(CCOperation)encryptOrDecrypt
{
CCCryptorStatus ccStatus   = kCCSuccess;
size_t          cryptBytes = 0;    // Number of bytes moved to buffer.
NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeDES];
uint8_t iv[kChosenCipherBlockSize];
memset((void *) iv, 0x0, (size_t) sizeof(iv));

ccStatus = CCCrypt( encryptOrDecrypt,
                   kCCAlgorithmDES,
                   kCCOptionPKCS7Padding,
                   symmetricKey.bytes, 
                   kCCKeySize3DES,
                   (const void *)iv,
                   dataIn.bytes,
                   dataIn.length,
                   dataOut.mutableBytes,
                   dataOut.length,
                   &cryptBytes);

if (ccStatus != kCCSuccess) {
    NSLog(@"CCCrypt status: %d", ccStatus);
}

dataOut.length = cryptBytes;

return dataOut;
}

Когда я пытаюсь закодировать «тестовое» сообщение в Java, я получаю «f69d7c299597c880», но на iOS (используя тот же ключ, конечно) я получаю «91864397> <41434eaa> "для 3DES и" <4bad6f7f> "для DES.Любые идеи о том, что еще я могу изменить?

Ответы [ 3 ]

3 голосов
/ 06 октября 2011

Это сложная проблема, потому что она либо работает, либо не очень мало подсказок.Лучший способ продолжить - начать как можно проще и собрать.

Первое, что нужно, это узнать, что именно делает код Java.В режиме CBC будет IV (значение инициализации), но ни один явно не указан в опубликованном коде Java.Вы должны выяснить, что использует код Java.Также опубликуйте полный код Java.

Из кода PaddedBufferedBlockCipher Я предполагаю, что существует заполнение блоков, это может быть PKCS5 или PKCS7, оба с точки зрения заполнения одинаковы, для iOS эквивалент kCCOptionPKCS7Padding,Убедитесь в этом.

Убедитесь, что длина ключа одинакова, для AES параметры 128, 192 и 256 бит, если нет особых причин, используйте 128.

Код Hex.encode кажется, подразумевает, что вывод кодируется в шестнадцатеричном формате, вам нужно сделать то же самое на iOS, это не то же самое, что Base64.

Другой основной проблемой является получение всех параметров одинаковыми с обеих сторон,Особый интерес представляют:

  1. значение и размер ключа шифрования
  2. режим: CBC, ECB и т. Д. (Вам, вероятно, следует использовать CBC)
  3. вектор инициализации (iv) необходим для большинства режимов
  4. метод заполнения: PKCS7 и т. д. (AES является блочным шифром и требует ввода, кратного размеру блока)
  5. Любая последующая обработка шифрования, hex или Base64кодирование.

Начните как можно проще, iv из всех 0, данные одного размера блока, без заполнения, простой ключ, без постобработки.Получите ключ, iv и тестовые данные из файла, который может быть разделен между системами, это предотвратит некоторые ошибки, такие как завершение строки c-jul и т. Д.1030 *

Также добавьте Security.framework в свой проект.

Если важна безопасность, подумайте о том, чтобы кто-нибудь с опытом в области безопасности создал код и протокол.Если безопасность не важна, просто отправьте пароль в открытом виде.

Несколько ошибок в приложении не так уж и плохи, приложение по-прежнему в основном работает, одна ошибка в безопасности и вся безопасность потеряна.

Хорошая безопасность не так проста, как можно подумать - или, как говорит моя жена: «Если бы крипто было легко, все бы это сделали», но она действительно имеет в виду правильно.

0 голосов
/ 17 октября 2011

Хорошо, я добился определенного прогресса (надеюсь). При проверке кода Java они используют размер блока 8 и DES / CBC с ключом из 24 символов. Поэтому я изменил код с CocoaFu на этот:

- (NSData *)doCipher:(NSData *)dataIn
             key:(NSData *)symmetricKey
         context:(CCOperation)encryptOrDecrypt
{
CCCryptorStatus ccStatus   = kCCSuccess;
size_t          cryptBytes = 0;    // Number of bytes moved to buffer.
NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeDES];
uint8_t iv[kChosenCipherBlockSize];
memset((void *) iv, 0x0, (size_t) sizeof(iv));

ccStatus = CCCrypt( encryptOrDecrypt,
                   kCCAlgorithmDES,
                   kCCOptionPKCS7Padding,
                   symmetricKey.bytes, 
                   kCCKeySize3DES,
                   (const void *)iv,
                   dataIn.bytes,
                   dataIn.length,
                   dataOut.mutableBytes,
                   dataOut.length,
                   &cryptBytes);

if (ccStatus != kCCSuccess) {
    NSLog(@"CCCrypt status: %d", ccStatus);
}

dataOut.length = cryptBytes;

return dataOut;
}

Когда я пытаюсь закодировать «тестовое» сообщение в Java, я получаю «f69d7c299597c880», но на iOS (конечно, используя тот же ключ) я получаю «<91864397> <41434eaa>» для 3DES и « <4bad6f7f> "для DES. Любые идеи о том, что еще я могу изменить?

0 голосов
/ 06 октября 2011

Вы пытаетесь использовать режим CBC на своем шифре, но iOS не поддерживает режим CBC, только ECB. Смотрите здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...