В соответствии с требованиями наших клиентов пароли пользователей должны храниться в некоторой «читаемой» форме, чтобы можно было конвертировать учетные записи позднее. К сожалению, просто сохранить хеш-значения и сравнить их при аутентификации здесь не вариант. Хранение простых паролей в базе данных, конечно, тоже не вариант, но можно использовать такую схему шифрования, как AES. Но в этом случае ключ для расшифровки паролей должен был бы храниться в системе, выполняющей аутентификацию, и мне это не совсем удобно.
В надежде получить «лучшее из обоих миров», моя реализация теперь использует RSA асимметричное шифрование для защиты паролей. Пароли засолены и зашифрованы с использованием открытого ключа. Я отключил любые дополнительные, внутренние механизмы соления или набивки. Зашифрованный пароль будет всегда один и тот же, как хешированный пароль MD5 или SHA1. Таким образом, системе аутентификации нужен только открытый ключ. Закрытый ключ не требуется.
Закрытый ключ распечатывается, запечатывается и хранится в автономном режиме в сейфе компании сразу после его создания. Но когда учетные записи необходимо преобразовать позже, это позволит получить доступ к паролям.
Прежде чем мы развернем это решение, я хотел бы услышать ваше мнение об этой схеме. Есть ли недостатки в дизайне? Есть ли серьезные недостатки по сравнению с симметричным шифрованием? Что-то еще нам не хватает?
Заранее большое спасибо!
-
Обновление:
В ответ на приведенные ниже аргументы Джека я хотел бы добавить соответствующие подробности реализации нашей функции хеширования на основе RSA:
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher rsa = Cipher.getInstance("RSA/None/NoPadding");
rsa.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cryptRaw = rsa.doFinal(saltedPassword.getBytes());
Быстро пролистав документ, упомянутый Джеком, я думаю, что немного понимаю важность предварительной обработки, такой как OAEP. Хорошо ли было бы расширить мой исходный вопрос и спросить, есть ли способ применить необходимую предварительную обработку и при этом иметь функцию, возвращающую один и тот же выход каждый раз для каждого входа, как это делает обычная функция хеширования? Я бы принял ответ на этот «бонусный вопрос» здесь. (Или я должен задать этот отдельный вопрос по SOF?)
-
Обновление 2:
Мне трудно принять один из настоящих ответов, потому что я чувствую, что никто не отвечает на мой вопрос. Но я больше не жду ответов, так что я приму тот, который я считаю наиболее конструктивным.