Расшифровать пример 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 ответа:
Прежде всего AES-это алгоритм симметричного шифрования, который должен использовать точно такой же ключ для шифрования сообщения, а также для расшифровки сообщения.
Я изучил ваши примеры кодов, и вот что меня действительно беспокоит:
Я считаю, что это основные причины, по которым вы не можете заставить его работать. Если вы хотите использовать AES, то вам нужно будет изменить свой код на Используйте один и тот же ключ на обоих устройствах, Используйте один и тот же режим шифрования на обоих устройствах, а также использовать ту же прокладку на обоих устройствах.
- различные ключи : пример Android не предоставляет никакого геттера или сеттера для ключа AES, который должен использоваться. Без этого вы не сможете использовать один и тот же ключ AES на Android и iOS.
- различные размеры клавиш : Android пример, кажется, использует AES-128, но пример iOS, кажется, использует AES-256
- различные режимы шифрования : пример iOS использует режим шифрования CBC, поэтому вам нужно будет также обмениваться IV (вектор инициализации) между вашими устройствами. Однако я не вижу никакого интерфейса для предоставления/приобретения IV в примере Android.
Советы:
Для этого можно использовать стороннюю библиотеку. В зависимости от библиотеки, она может быть кроссплатформенной, так что одни и те же вызовы на разных платформах будут возвращать одни и те же результаты.
Безопасный Черный Ящик: 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