Reputation: 1435
To reset my password I want to send the user a link to site/account/{hash} where {hash} is a hash of the user's password and a timestamp.
I have the following code to hash only the email and have a readable link:
String check = info.mail;
MessageDigest md = MessageDigest.getInstance("SHA-1");
String checkHash = Base64.encodeBase64String(md.digest(check.getBytes()));
if(checkHash.equals(hash)){
return ResponseEntity.ok("Password reset to: " + info.password);
}else{
return ResponseEntity.ok("Hash didn't equal to: " + checkHash);
}
The problem is that when I convert this to Base64 it may include / signs what will mess up my links and checking of the hash. I can simply replace any unwanted signs by something else after the hashing but is there some other way to have your hash only include a certain part of codes?
Also I know the returns are still sent unsafe but this is just for testing and debugging.
Upvotes: 2
Views: 586
Reputation: 14355
The RFC 3548 specifies a variant often called "base64url" specifically designed for that purpose. In this variant, +
and /
are replaced by -
and _
.
Java 8 has built-in support with the new Base64 class. If you're stuck with an older version, the Base64 class of Apache Commons can be configured to be url safe by using the new Base64(true)
constructor.
Other options might be:
Don't use Base64, but transfer the bytes as hexadecimal representation (which will not contain any special characters):
String checkHash = toHex(md.digest(check.getBytes()));
with
private static String toHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X", b));
}
return sb.toString();
}
Use URL encoding/decoding on the generated hash (that's what you already know)
Upvotes: 2