Я разрабатываю модуль входа в систему с помощью JSP/Servlets/MySQL с алгоритмом RSA. Как только я зарегистрирую нового пользователя, я сохраняю PublicKey в MySQL и шифрую с ним пароль.Java RSA, почему каждый раз зашифрованный текст?
Когда пользователь пытается войти в систему, я извлекаю этот PublicKey и шифрую только что введенный пароль с соответствующим PublicKey и сравниваю его с ранее сохраненным зашифрованным паролем, но он всегда возвращает другой шифрованный текст ,
Я не могу понять, почему я получаю разные зашифрованные пароли каждый раз. Есть ли что-то, что я делаю неправильно? Создает ли он новый PublicKey каждый раз, когда он запускает «keyFactory.generatePublic»?
Спасибо за вашу помощь
Мой метод для создания открытого ключа является:
public byte[] generateBytePublicKey() throws Exception {
byte[] pk = null;
try {
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
keyGen.initialize(1024);
pk = keyGen.generateKeyPair().getPublic().getEncoded();
} (...... etc etc)
return pk;
Мой метод шифрования пароля:
public byte[] encryptBytes(String pwd, byte[] key) throws Exception {
byte[] cipherText = null;
PublicKey pk;
try {
byte[] dataBytes = pwd.getBytes();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
pk = keyFactory.generatePublic(new X509EncodedKeySpec(key));
final Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pk);
cipherText = cipher.doFinal(dataBytes);
} (..... etc etc)
return cipherText;
Мой метод хранить зашифрованный пароль и открытый ключ в таблице MySQL:
(.....................)
try {
Statement stmt = null;
ResultSet rs = null;
byte[] bytePublicKey;
byte[] cipherPwd;
bytePublicKey = generateBytePublicKey();
cipherPwd = encryptBytes(password, bytePublicKey);
String query = "INSERT INTO Users (email, pwd, publickey) VALUES ('" + email + "', ?, ?)";
PreparedStatement ps;
ps = conn.getConexion().prepareStatement(query);
ps.setBytes(1, cipherPwd);
ps.setBytes(2, bytePublicKey);
resultSet = ps.executeUpdate();
} (............. etc etc)
Мой метод для проверки, если пользователь является действительным:
public boolean isUserValid (String email, String typedPassword) throws Exception {
byte[] storedBytesPassword;
byte[] storedBytesPublicKey;
byte[] typedPwdtoBytes;
try {
storedBytesPublicKey = getByteArrays(email, "publicKey");
storedBytesPassword = getByteArrays(email, "pwd");
typedPwdtoBytes = encryptBytes(typedPassword, storedBytesPublicKey);
return Arrays.equals(typedPwdtoBytes, storedBytesPassword);
} (............. etc etc)
Мой метод, чтобы получить массив байтов из MySQL таблицы:
public byte[] getByteArrays (String email, String byteArray) throws SQLException {
(..............)
try {
Statement stmt=null;
ResultSet rs=null;
query = "SELECT " + byteArray + " FROM Users WHERE email = '" + email + "'";
try {
stmt = (conn.getConexion()).createStatement();
rs = stmt.executeQuery(query);
while (rs.next()) {
bytesArr = rs.getBytes(1);
} (.................. etc etc)
Вы генерируете пару ключей RSA только для того, чтобы выбросить закрытый ключ и по существу сделать шифрование улицей с односторонним движением. Существуют более простые альтернативы, такие как использование PBKDF2 со случайной солью и много итераций. На [security.se]: [Как безопасно использовать хэш-пароли?] (http://security.stackexchange.com/q/211/45523) –