Расшифровать пример android AES на iOS


У меня есть пример Андроида шифрования AES/описание.

Https://github.com/itog/CryptoSample/blob/master/src/com/pigmal/android/ex/crypto/Crypto.java#L35

Я хочу расшифровать это на iOS. Это выглядит совершенно невозможным. Я нашел это, чтобы сделать его более легким, но потерпел неудачу:

Https://github.com/Gurpartap/AESCrypt-ObjC

Я даже не получаю хорошего ответа от декодирования base64. Вот мой код:

NSData *encryptedData = [NSData base64DataFromString:encrypted];
// returns null
NSData *decryptedData = [encryptedData decryptedAES128DataUsingKey:[[CRYPT_SEED dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash] error:&error];
NSString* result = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
4 4

4 ответа:

Прежде всего AES-это алгоритм симметричного шифрования, который должен использовать точно такой же ключ для шифрования сообщения, а также для расшифровки сообщения.

Я изучил ваши примеры кодов, и вот что меня действительно беспокоит:

  • различные ключи : пример Android не предоставляет никакого геттера или сеттера для ключа AES, который должен использоваться. Без этого вы не сможете использовать один и тот же ключ AES на Android и iOS.
  • различные размеры клавиш : Android пример, кажется, использует AES-128, но пример iOS, кажется, использует AES-256
  • различные режимы шифрования : пример iOS использует режим шифрования CBC, поэтому вам нужно будет также обмениваться IV (вектор инициализации) между вашими устройствами. Однако я не вижу никакого интерфейса для предоставления/приобретения IV в примере Android.
Я считаю, что это основные причины, по которым вы не можете заставить его работать. Если вы хотите использовать AES, то вам нужно будет изменить свой код на Используйте один и тот же ключ на обоих устройствах, Используйте один и тот же режим шифрования на обоих устройствах, а также использовать ту же прокладку на обоих устройствах.

Советы:

    Для этого можно использовать стороннюю библиотеку. В зависимости от библиотеки, она может быть кроссплатформенной, так что одни и те же вызовы на разных платформах будут возвращать одни и те же результаты.

Безопасный Черный Ящик: https://www.eldos.com/sbb/platforms.php#product

Crypto++ http://www.cryptopp.com

  • Вы можете скомпилировать тестовую процедуру AES, чтобы гарантировать, что обе процедуры AES encrypt и decrypt на Android и iOS дают то же самое результаты.

  • Вы можете проверить Base64, если он кодирует и декодирует правильно. Иногда это может быть проблема Unicode (UTF16) iOS и non-Unicode (UTF8) Android. Это случилось со мной, когда я делал это.

Ну, это может быть потому, что открытые ключи разные.

Есть две вещи, которые хранятся в зашифрованном виде. Первый-это имя пользователя / пароль, а второй-само сообщение. При правильном вводе пароля сообщение расшифровывается с помощью вашего пароля и открытого ключа.

Причина, по которой мы называем егооткрытым ключом , заключается в том, что для одних и тех же методов шифрования ключи одинаковы.

Поэтому я думаю, что, возможно, вам следует поискать процедуру, которая устанавливает открытый ключ в строку по вашему выбору.

Или вы можете использовать более простой метод, такой как fairplay.

То, что другие ответы отметили, верно, это может привести к различному размеру ключа/режиму/заполнению. Также могут быть проблемы с типом BASE64 кодировки. На Android есть несколько различных флагов, которые могут производить тонко различные выходы. Я нашел Base64.NO_WRAP, чтобы работать.

У меня также была подобная проблема с AESCrypt-ObjC по умолчанию он использует пустой IV и на Android/Java кажется, что если вы не указываете один, генерируется случайный.

Вот как я указал пустой IV, чтобы iOS могла расшифровать:

private static byte[] ivBytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);

cipherText = cipher.doFinal(stuffIWantSafe.getBytes("UTF-8"));

String encodedCipherText = Base64.encodeToString(cipherText, Base64.NO_WRAP);

отказ от ответственности: я не рекомендую пустой IV с точки зрения безопасности, чтобы лучше иметь IV, который меняется с каждым сообщением

*Обновление: только что выпущена Android-Версия AESCrypt