diff --git a/deegree-services/deegree-webservices/src/main/java/org/deegree/console/security/LogBean.java b/deegree-services/deegree-webservices/src/main/java/org/deegree/console/security/LogBean.java
index 24c618d288..9912a8850b 100644
--- a/deegree-services/deegree-webservices/src/main/java/org/deegree/console/security/LogBean.java
+++ b/deegree-services/deegree-webservices/src/main/java/org/deegree/console/security/LogBean.java
@@ -113,7 +113,7 @@ public String getNewPassword2() {
return newPassword2;
}
- public String logIn() throws NoSuchAlgorithmException, IOException {
+ public String logIn() throws IOException {
SaltedPassword storedPassword = passwordFile.getCurrentContent();
if (storedPassword == null) {
@@ -125,7 +125,7 @@ public String logIn() throws NoSuchAlgorithmException, IOException {
SaltedPassword givenPassword = new SaltedPassword(currentPassword, storedPassword.getSalt());
loggedIn = storedPassword.equals(givenPassword);
- LOG.debug("Provided password matches stored password. Successfully logged in.");
+ LOG.debug("Provided password matches stored password: {}", loggedIn);
return FacesContext.getCurrentInstance().getViewRoot().getViewId();
}
diff --git a/deegree-services/deegree-webservices/src/main/java/org/deegree/console/security/PasswordFile.java b/deegree-services/deegree-webservices/src/main/java/org/deegree/console/security/PasswordFile.java
index 4ac847e329..6f2adffd54 100644
--- a/deegree-services/deegree-webservices/src/main/java/org/deegree/console/security/PasswordFile.java
+++ b/deegree-services/deegree-webservices/src/main/java/org/deegree/console/security/PasswordFile.java
@@ -28,6 +28,7 @@
package org.deegree.console.security;
import static java.lang.Character.digit;
+import static org.deegree.console.security.SaltedPassword.SHA256_PREFIX;
import java.io.BufferedReader;
import java.io.File;
@@ -96,7 +97,7 @@ private SaltedPassword parseSaltedPassword(String encoded) throws IOException {
}
String[] parts = encoded.split("\\$");
- return new SaltedPassword(parts[3].getBytes(StandardCharsets.UTF_8), parts[2]);
+ return new SaltedPassword(parts[3].getBytes(StandardCharsets.UTF_8), SHA256_PREFIX + parts[2]);
}
/**
diff --git a/deegree-services/deegree-webservices/src/main/java/org/deegree/console/security/SaltedPassword.java b/deegree-services/deegree-webservices/src/main/java/org/deegree/console/security/SaltedPassword.java
index f058d228c4..f89d9b34bd 100644
--- a/deegree-services/deegree-webservices/src/main/java/org/deegree/console/security/SaltedPassword.java
+++ b/deegree-services/deegree-webservices/src/main/java/org/deegree/console/security/SaltedPassword.java
@@ -71,10 +71,12 @@
* @see Unix crypt using SHA-256
* and SHA-512
*/
-public class SaltedPassword {
+public final class SaltedPassword {
private static final String CHARSET = StandardCharsets.UTF_8.toString();
+ static final String SHA256_PREFIX = "$5$";
+
private final byte[] saltedAndHashedPassword;
private final String salt;
@@ -86,19 +88,20 @@ public SaltedPassword(byte[] saltedAndHashedPassword, String salt) {
public SaltedPassword(String plainPassword, String salt) throws UnsupportedEncodingException {
byte[] plainPasswordBinary = plainPassword.getBytes(CHARSET);
- String saltedPassword = generateHashedAndSaltedPassword(plainPasswordBinary);
+ String saltedPassword = Sha2Crypt.sha256Crypt(plainPasswordBinary, salt);
int delimiterPos = nthIndexOf(saltedPassword, "$", 3);
- this.salt = saltedPassword.substring(0, delimiterPos);
this.saltedAndHashedPassword = saltedPassword.substring(delimiterPos + 1, saltedPassword.length())
.getBytes(StandardCharsets.UTF_8);
+ this.salt = salt;
}
public SaltedPassword(String plainPassword) throws UnsupportedEncodingException {
- this(plainPassword, null);
- }
-
- private String generateHashedAndSaltedPassword(byte[] plainPassword) {
- return Sha2Crypt.sha256Crypt(plainPassword);
+ byte[] plainPasswordBinary = plainPassword.getBytes(CHARSET);
+ String saltedPassword = Sha2Crypt.sha256Crypt(plainPasswordBinary);
+ int delimiterPos = nthIndexOf(saltedPassword, "$", 3);
+ this.salt = saltedPassword.substring(0, delimiterPos);
+ this.saltedAndHashedPassword = saltedPassword.substring(delimiterPos + 1, saltedPassword.length())
+ .getBytes(StandardCharsets.UTF_8);
}
public byte[] getSaltedAndHashedPassword() {
diff --git a/deegree-services/deegree-webservices/src/test/java/org/deegree/console/security/PasswordFileTest.java b/deegree-services/deegree-webservices/src/test/java/org/deegree/console/security/PasswordFileTest.java
index 64424fd901..c0a1c1ee97 100644
--- a/deegree-services/deegree-webservices/src/test/java/org/deegree/console/security/PasswordFileTest.java
+++ b/deegree-services/deegree-webservices/src/test/java/org/deegree/console/security/PasswordFileTest.java
@@ -1,9 +1,11 @@
package org.deegree.console.security;
import static org.deegree.console.security.LogBean.PASSWORD_FILE;
+import static org.deegree.console.security.SaltedPassword.SHA256_PREFIX;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.isEmptyOrNullString;
+import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertTrue;
import java.io.File;
@@ -22,6 +24,11 @@
*/
public class PasswordFileTest {
+ /**
+ * This unit tests can validate if the existing console.pw file contains a password in
+ * the new extended password format introduced with deegree version 3.6.
+ * @throws IOException in case of errors
+ */
@Test
@Ignore
public void getCurrentContentFromWorkspaceRoot() throws IOException {
@@ -31,14 +38,16 @@ public void getCurrentContentFromWorkspaceRoot() throws IOException {
assertTrue(passwordFileFQN.isFile());
PasswordFile passwordFile = new PasswordFile(passwordFileFQN);
assertTrue(passwordFile.exists());
- assertThat(passwordFile.getCurrentContent().toString(), not(isEmptyOrNullString()));
+ SaltedPassword saltedPassword = passwordFile.getCurrentContent();
+ assertThat(saltedPassword.toString(), not(isEmptyOrNullString()));
+ assertThat(saltedPassword.getSalt(), startsWith(SHA256_PREFIX));
}
/**
* Attention: Enabling this unit test will overwrite the content of the console.pw
* file! This test is intended as an example how to create a valid console.pw file
* with the new extended passwort format introduced with deegree version 3.6.
- * @throws IOException
+ * @throws IOException in case of errors
* @since 3.6
* @see SaltedPassword
*/
diff --git a/deegree-services/deegree-webservices/src/test/java/org/deegree/console/security/SaltedPasswordTest.java b/deegree-services/deegree-webservices/src/test/java/org/deegree/console/security/SaltedPasswordTest.java
index 3f8ac054bd..a21ff84098 100644
--- a/deegree-services/deegree-webservices/src/test/java/org/deegree/console/security/SaltedPasswordTest.java
+++ b/deegree-services/deegree-webservices/src/test/java/org/deegree/console/security/SaltedPasswordTest.java
@@ -5,8 +5,10 @@
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
+import static org.deegree.console.security.SaltedPassword.SHA256_PREFIX;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.assertTrue;
/**
* @author Torsten Friebe
@@ -18,7 +20,7 @@ public class SaltedPasswordTest {
public void testCreatingFromPlainPassword() throws UnsupportedEncodingException {
SaltedPassword plainpassword = new SaltedPassword("foo");
String saltedPassword = new String(plainpassword.getSaltedAndHashedPassword(), StandardCharsets.UTF_8);
- assertThat(plainpassword.getSalt(), startsWith("$5$"));
+ assertThat(plainpassword.getSalt(), startsWith(SHA256_PREFIX));
assertThat(saltedPassword, is(notNullValue()));
}
@@ -31,6 +33,15 @@ public void testCreatingFromSaltedPassword() {
assertThat(saltedpassword.getSalt(), is(salt));
}
+ @Test
+ public void testCreateNewPasswordWithSaltFromOtherPassword() throws UnsupportedEncodingException {
+ String plainpassword = "foo";
+ SaltedPassword storedPassword = new SaltedPassword(plainpassword);
+ String saltFromStoredPassword = storedPassword.getSalt();
+ SaltedPassword givenPassword = new SaltedPassword(plainpassword, saltFromStoredPassword);
+ assertTrue(storedPassword.equals(givenPassword));
+ }
+
@Test
public void testSaltedPasswordAsParts() throws UnsupportedEncodingException {
SaltedPassword password = new SaltedPassword("foo");
@@ -46,6 +57,4 @@ public void testSaltedPasswordAsParts() throws UnsupportedEncodingException {
assertThat(parts[3], hasLength(43));
}
-
-
}
\ No newline at end of file