Алгоритм TripleDES генерирует другой результат при вызове с Android - PullRequest
0 голосов
/ 27 сентября 2011

У меня есть простое веб-приложение на Java, созданное Apache Wicket. Когда я регистрирую пользователей в веб-приложении, я шифрую пароль, который они вводят, используя тройки, и сохраняю его в базу данных. На странице входа в систему, когда они вводят один и тот же пароль, я шифрую его и передаю зашифрованный пароль в БД, чтобы проверить, верен ли он.

Сейчас я работаю над созданием приложения для Android, которое будет иметь те же функции входа в систему.

На странице входа в приложение Android я использую одну и ту же библиотеку шифрования для шифрования пароля и использую один и тот же ключ и вектор инициализации для обеих платформ, но если я пытаюсь ввести одну и ту же строку пароля в Android, алгоритм TripleDes генерирует совершенно разные зашифрованные пароль (намного дольше). И, следовательно, вход не удается с устройства Android Я также заметил, что зашифрованный пароль, который генерирует Android, не может быть расшифрован, он выдает исключение.

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

Вот алгоритм, который я использую:

public class TripleDES {
private String key;
private byte[] initializationVector;

public TripleDES(String key, byte[] initializationVector)
{
    this.key = key;
    this.initializationVector = initializationVector;
}

public String encryptText(String plainText) throws Exception{
//----  Use specified 3DES key and IV from other source -------------------------
  byte[] plaintext = plainText.getBytes();
  byte[] tdesKeyData = key.getBytes();

  System.out.println("plain text length: " + plaintext.length);
  System.out.println("key length: " + tdesKeyData.length);


  Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
  SecretKeySpec    myKey = new SecretKeySpec(tdesKeyData, "DESede");
  IvParameterSpec ivspec = new IvParameterSpec(initializationVector);

  c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
  byte[] cipherText = c3des.doFinal(plaintext);

  return Base64Coder.encodeString(new String(cipherText));
}

public String decryptText(String encryptedText) throws Exception{
    //----  Use specified 3DES key and IV from other source -------------------
      byte[] enctext = Base64Coder.decode(encryptedText);
      byte[] tdesKeyData = key.getBytes();


      Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
      SecretKeySpec    myKey = new SecretKeySpec(tdesKeyData, "DESede");
      IvParameterSpec ivspec = new IvParameterSpec(initializationVector);

      c3des.init(Cipher.DECRYPT_MODE, myKey, ivspec);
      byte[] cipherText = c3des.doFinal(enctext);
      return new String(cipherText);
    }

}

1 Ответ

2 голосов
/ 27 сентября 2011

(РЕДАКТИРОВАТЬ: Как уже отмечалось, реверсивное хранение паролей - плохая идея для начала, но ради правильной части шифрования ...)

Вот первая проблема:

byte[] plaintext = plainText.getBytes();
byte[] tdesKeyData = key.getBytes();

Это использует системную кодировку по умолчанию.Это одинаково на всех телефонах Android?Я не знаю.Это то же самое в Android, что и на вашем веб-сервере?Я не знаю.Если одна платформа использует UTF-16, а другая использует UTF-8 и plainText - это все ASCII, это, безусловно, будет учитывать разницу в два раза в размере зашифрованных данных.

Iрекомендовал бы всегда с указанием кодировки - «UTF-8» является хорошим выбором во многих случаях.

РЕДАКТИРОВАТЬ: Хорошо, похоже, проблема была также чтоВы тогда сделали позже с cipherText.Вам необходимо преобразовать необработанные байты в строку base64.В Android встроен кодировщик base64, но этот общедоступный код должен нормально работать.Вместо этой строки:

return Base64Coder.encodeString(new String(cipherText));

вы бы использовали

return Base64.encodeBytes(cipherText);
...