Во-первых, я настоятельно рекомендую не разрабатывать новые форматы шифрования, если вы можете помочь. Это очень сложно сделать правильно. Если вам нужен формат шифрования, который соответствует тому, что вы описываете, см. JNCryptor , который является реализацией формата RNCryptor . Формат RNCryptor разработан именно для этой проблемы, поэтому спецификация является хорошим источником информации о том, как вы можете создать свой собственный, если вы не хотите использовать его напрямую. (Я автор RNCryptor.)
См. Также libsodium . Это лучший формат шифрования, чем RNCryptor по различным техническим причинам, но его сложнее установить и использовать правильно. Для libsodium есть несколько привязок Java .
Когда вы говорите «конечно, я не реализовывал криптографию сам», это то, что вы делаете. Крипто-схемы - это больше, чем просто код AES. Решение о том, как генерировать соли новым способом, - это реализация крипто. Есть много способов собрать безопасные примитивы (например, соли) простыми способами и сделать их дико незащищенными. Вот почему вы хотите использовать что-то устоявшееся.
Ключевым выводом является то, что вы храните соль с данными. Я знаю, ты сказал, что дело не в хранении соли, а в том, как ты это делаешь. Самый простой способ сделать это - просто приклеить соль к началу текста шифра и сохранить его. Тогда вы просто читаете соль из шапки. Точно так же вы можете положить все это в конверт, если это более удобно. Что-то простое, как JSON:
{ "salt": "<base64-salt>",
"data": "<base64-data>" }
Это не самый эффективный способ хранения данных, но он простой, стандартный и безопасный.
Помните, соли не являются секретами. Хорошо, что каждый может читать соль.
Хорошо, хватит о том, как сделать это правильно. Давайте вернемся к вашему актуальному вопросу.
Ваше соленое предложение не является солью. Это просто немного другая функция хеширования. Смысл в том, что если один и тот же пароль используется дважды (без намерения быть одним и тем же паролем), то они будут иметь разные хэши. Ваша схема не справляется с этим. Если я использую тот же подход, что и вы, и выбираю тот же пароль, что и ваш, то хеш будет таким же. Радужные столы выигрывают.
Способ, которым вы исправляете, используя статическую соль, а не модифицированную хеш-функцию. Вы должны выбрать соль, которая представляет вашу систему. Мне обычно нравится обратный DNS для этого, потому что это приводит к уникальности. Например: «com.example.mygreatapp». Кто-то, естественно, выберет «org.example.ourawesomedb». Вы также можете выбрать длинную случайную строку, но важна уникальность, поэтому мне нравится обратный DNS. (Случайные строки заставляют людей думать, что соль - это секрет, а соль - , а не - секрет.)
Вот и вся система; просто выберите постоянную соль, уникальную для вашей системы. (Если бы у вас было имя пользователя, вы бы добавили имя пользователя к соли. Это стандартный способ построения детерминированной соли.)
Но для хранения файлов я бы никогда так не поступил.