Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,19 @@
import org.apache.shiro.crypto.hash.format.HashFormat;
import org.apache.shiro.crypto.hash.format.HashFormatFactory;
import org.apache.shiro.crypto.hash.format.ParsableHashFormat;
import org.apache.shiro.crypto.hash.format.Shiro1CryptFormat;
import org.apache.shiro.crypto.hash.format.Shiro2CryptFormat;
import org.apache.shiro.lang.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.MessageDigest;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.Objects.requireNonNull;
import static org.apache.shiro.crypto.hash.SimpleHashProvider.Parameters.PARAMETER_ITERATIONS;

/**
* Default implementation of the {@link PasswordService} interface that relies on an internal
Expand Down Expand Up @@ -111,7 +116,13 @@ public boolean passwordsMatch(Object plaintext, Hash saved) {
}
}

return saved.matchesPassword(plaintextBytes);
if (hashFormat instanceof Shiro1CryptFormat) {
HashRequest request = createHashRequest(plaintextBytes, saved);
Hash computed = hashService.computeHash(request);
return constantEquals(saved.toString(), computed.toString());
} else {
return saved.matchesPassword(plaintextBytes);
}
}

private boolean constantEquals(String savedHash, String computedHash) {
Expand Down Expand Up @@ -146,6 +157,20 @@ protected HashRequest createHashRequest(ByteSource plaintext) {
.build();
}

protected HashRequest createHashRequest(ByteSource plaintext, Hash saved) {
Map<String, Object> parameters = Stream.concat(getHashService().getParameters().entrySet().stream(),
Map.of(PARAMETER_ITERATIONS, saved.getIterations()).entrySet().stream())
.collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue,
(value1, value2) -> value2));
//keep everything from the saved hash except for the source:
return new HashRequest.Builder().setSource(plaintext)
//now use the existing saved data:
.setAlgorithmName(saved.getAlgorithmName())
.setSalt(saved.getSalt())
.withParameters(parameters)
.build();
}

protected ByteSource createByteSource(Object o) {
return ByteSource.Util.bytes(o);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,4 @@ public interface ConfigurableHashService extends HashService {
* compute secure hashes for passwords.
*/
void setDefaultAlgorithmName(String name);

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
package org.apache.shiro.crypto.hash;

import java.security.SecureRandom;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.Random;

Expand Down Expand Up @@ -49,6 +51,7 @@ public class DefaultHashService implements ConfigurableHashService {
*/
private String defaultAlgorithmName;

private Map<String, Object> parameters = Map.of();

/**
* Constructs a new {@code DefaultHashService} instance with the following defaults:
Expand Down Expand Up @@ -112,4 +115,13 @@ public String getDefaultAlgorithmName() {
return this.defaultAlgorithmName;
}

@Override
public Map<String, Object> getParameters() {
return Collections.unmodifiableMap(this.parameters);
}

@Override
public void setParameters(Map<String, Object> parameters) {
this.parameters = parameters;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*/
package org.apache.shiro.crypto.hash;

import java.util.Map;

/**
* A {@code HashService} hashes input sources utilizing a particular hashing strategy.
* <p/>
Expand Down Expand Up @@ -80,4 +82,20 @@ public interface HashService {
* @since 2.0
*/
String getDefaultAlgorithmName();

/**
* Returns the various parameters that will be used when computing hashes.
*
* @return the various parameters that will be used when computing hashes.
*/
default Map<String, Object> getParameters() {
return Map.of();
}

/**
* Sets the various parameters that will be used when computing hashes.
*
* @param parameters the various parameters that will be used when computing hashes.
*/
default void setParameters(Map<String, Object> parameters) { }
}
Loading