Безопасное хранение пароля в Java программе
Пишу простую программу на Java, которая периодически подключается к серверу. При отправке каждого запроса на сервер мне нужно передать и логин и пароль. Программа работает на моем компьютере на OS Windows. Как безопасно хранить пароли и в то же время каждый раз не вводить их?
Ответы (2 шт):
Автор решения: lampa
→ Ссылка
Сохранить логин/пароль в файл для хранения, предварительно запаролив и при каждом запуске программы вводить ключ, например так:
package com.lampa.keys;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.util.Arrays;
public class Main {
// функция для шифровки и дешифровки сообщения
public static byte[] crypt(int mode, byte[] value, String secret) throws Exception {
byte[] key = secret.getBytes(StandardCharsets.UTF_8);
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(mode, secretKey);
return cipher.doFinal(value);
}
public static void main(String[] args) {
// файл, где будем хранить логин и пароль
File passwordFile = new File("passwords.key");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String login = "";
String password = "";
// если файл существует, то пытаемся его прочитать с помощью ключа
if(passwordFile.exists()) {
try {
byte[] encrypted = Files.readAllBytes(passwordFile.toPath());
System.out.println("Write key");
String key = reader.readLine();
String[] result = new String(crypt(Cipher.DECRYPT_MODE, encrypted, key), StandardCharsets.UTF_8).split(":");
login = result[0];
password = result[1];
}
catch (Exception ex) {
System.err.printf("error read password from file %s", ex.getMessage());
}
}
// если файл не существует, то создаем его и шифруем ключом
else {
try {
System.out.println("Write login");
login = reader.readLine();
System.out.println("Write password");
password = reader.readLine();
System.out.println("Write key");
String key = reader.readLine();
FileOutputStream outputStream = new FileOutputStream(passwordFile);
outputStream.write(crypt(Cipher.ENCRYPT_MODE, (login + ":" + password).getBytes(StandardCharsets.UTF_8), key));
outputStream.close();
}
catch (Exception ex) {
System.err.printf("error write password to file %s", ex.getMessage());
}
}
System.out.printf("login: %s, password: %s%n", login, password);
}
}
Автор решения: palshyn
→ Ссылка
В результате выбрал хранение пароля в windows credential manager. Вот проект на основе библиотеки java jna: https://github.com/dariusz-szczepaniak/java.jna.WindowsCredentialManager