Большинство экземпляров Java Key
представлены в виде строки байтов, полученной в результате их метода getEncoded()
. Это то, что нужно сохранить, чтобы позже восстановить ключ.
Однако для безопасного хранения ключа в электронном виде он должен быть зашифрован. Конечно, для шифрования ключа потребуется другой ключ (или пароль) & hellip; и поэтому у вас есть бесконечный регресс. Java KeyStore
может использоваться для хранения SecretKey
объектов таким способом, и это полезно, когда у вас есть много секретных ключей, которые все защищены одним «главным» паролем. Но для защиты одного ключа это не имеет большого смысла.
Одной из альтернатив является предоставление пользователю ключа в форме, которая может быть сохранена безопасным способом (во многих приложениях, которые могут быть на бумажке в кошельке). Это может быть так же просто, как отобразить байты ключа, закодированного в шестнадцатеричном, Base-64 или другом текстовом кодировании, и попросить пользователя записать его.
Другой подход заключается в том, чтобы позволить пользователю выбрать запоминающийся пароль и с его помощью сгенерировать ключ, используя алгоритм типа PBKDF2. Соль (и, возможно, счетчик итераций), используемая для получения ключа, должна быть где-то записана. Другим недостатком является то, что люди склонны выбирать из относительно ограниченного количества паролей из общего числа доступных. Таким образом, ключи, полученные из паролей, могут быть легче угадать, чем предполагает размер ключа.
Вот иллюстрация основного метода сохранения и восстановления секретного ключа.
byte[] encoded = aesKey.getEncoded();
/* Now store "encoded" somewhere. For example, display the key and
ask the user to write it down. */
String output = Base64.getEncoder().withoutPadding().encodeToString(encoded);
System.out.println("Keep it secret, keep it safe! " + output);
...
/* At some point, you need to reconstitute the key. Let's say the user
enters it as a base-64 number that you convert to bytes. */
String input = ... ;
byte[] encoded = Base64.getDecoder().decode(input);
SecretKey aesKey = new SecretKeySpec(encoded, "AES");