*
* @param string string to be hashed
* @param hashKeyHex hash key received from the Miniserver in hex format
+ * @param sha256 if SHA-256 algorithm should be used (SHA-1 otherwise)
* @return hashed string or null if failed
*/
- String hashString(String string, String hashKeyHex) {
+ String hashString(String string, String hashKeyHex, boolean sha256) {
if (string == null || hashKeyHex == null) {
return null;
}
try {
+ String alg = sha256 ? "HmacSHA256" : "HmacSHA1";
byte[] hashKeyBytes = HexUtils.hexToBytes(hashKeyHex);
- SecretKeySpec signKey = new SecretKeySpec(hashKeyBytes, "HmacSHA1");
- Mac mac = Mac.getInstance("HmacSHA1");
+ SecretKeySpec signKey = new SecretKeySpec(hashKeyBytes, alg);
+ Mac mac = Mac.getInstance(alg);
mac.init(signKey);
byte[] rawData = mac.doFinal(string.getBytes());
return HexUtils.bytesToHex(rawData);
private class LxResponseKeySalt {
String key;
String salt;
+ String hashAlg;
}
/**
private int tokenRefreshRetryCount;
private ScheduledFuture<?> tokenRefreshTimer;
private final Lock tokenRefreshLock = new ReentrantLock();
+ private boolean sha256 = false;
private final byte[] initVector = new byte[IV_LENGTH_BYTES];
private final Logger logger = LoggerFactory.getLogger(LxWsSecurityToken.class);
}
}
- private String hashCredentials(LxResponseKeySalt keySalt) {
+ private String hashCredentials(LxResponseKeySalt keySalt, boolean sha256) {
try {
- MessageDigest msgDigest = MessageDigest.getInstance("SHA-1");
+ MessageDigest msgDigest = MessageDigest.getInstance(sha256 ? "SHA-256" : "SHA-1");
String pwdHashStr = password + ":" + keySalt.salt;
byte[] rawData = msgDigest.digest(pwdHashStr.getBytes(StandardCharsets.UTF_8));
String pwdHash = HexUtils.bytesToHex(rawData).toUpperCase();
logger.debug("[{}] PWDHASH: {}", debugId, pwdHash);
- return hashString(user + ":" + pwdHash, keySalt.key);
+ return hashString(user + ":" + pwdHash, keySalt.key, sha256);
} catch (NoSuchAlgorithmException e) {
logger.debug("[{}] Error hashing token credentials: {}", debugId, e.getMessage());
return null;
if (keySalt == null) {
return setError(null, "Error parsing hash key/salt json: " + resp.getValueAsString());
}
-
+ if ("SHA256".equals(keySalt.hashAlg)) {
+ sha256 = true;
+ }
logger.debug("[{}] Hash key: {}, salt: {}", debugId, keySalt.key, keySalt.salt);
// Hash user name, password, key and salt
- String hash = hashCredentials(keySalt);
+ String hash = hashCredentials(keySalt, sha256);
if (hash == null) {
return false;
}
try {
String hashKey = resp.getValueAsString();
// here is a difference to the API spec, which says the string to hash is "user:token", but this is "token"
- String hash = hashString(token, hashKey);
+ String hash = hashString(token, hashKey, sha256);
if (hash == null) {
setError(null, "Error hashing token.");
}