我正在 Spring-MVC 应用程序中工作,对于密码重置功能,我正在发送一封电子邮件,其中包含用户名+Joda 日期。在发送之前,我想以可以完美反转的方式对内容(日期+用户名)进行加密。就我的理论理解而言,逆向不是首先就违背了加密的目的吗?如果没有,那么我想对它们进行加密,然后使用某种机制来解密它们。我找到了一些解决方案,其中一个提到检索,但我无法弄清楚哪个实体是哪个。我粘贴下面的代码。请看一下:
加密和解密:
byte[] userBytes = username.getBytes("UTF-8");
byte[] keyBytes = key.getBytes("UTF-8");
//XOR scramble
byte[] encrypted = new byte[userBytes.length];
for(int i = 0; i < userBytes.length; i++){
encrypted[i] = (byte)(userBytes[i] ^ keyBytes[i % keyBytes.length]);
}
BASE64Encoder encoder = new BASE64Encoder();
String encoded = encoder.encode(encrypted);
// webappB, decode the parameter
BASE64Decoder decoder = new BASE64Decoder();
byte[] decoded = decoder.decodeBuffer( encoded );
//XOR descramble
byte[] decrypted = new byte[decoded.length];
for(int i = 0; i < decoded.length; i++){
decrypted[i] = (byte)(decoded[i] ^ keyBytes[i % keyBytes.length] );
}
最佳答案
此类有两个公共(public)方法,一个用于生成 token ,另一个用于验证 token 。它是从更大、更复杂的代码中删减的,因此可能会引入一些错误。还嵌入了一些测试,因此您可以立即使用它。无论如何,我希望这足以让您走上正轨。
package tokens;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class TokenUtils {
private static final String HMAC_ALGO = "HmacSHA256";
private static final String TOKEN_SEPARATOR = ":";
private static final long MAX_AGE = 1_000 * 60 * 60 * 24; // 24h
private TokenUtils() {
}
public static String createToken(String username, long timestamp, String secretKey) throws InvalidKeyException, NoSuchAlgorithmException {
StringBuilder sb = new StringBuilder();
sb.append(generateTokenStringPublicPart(username, timestamp));
sb.append(TOKEN_SEPARATOR);
sb.append(computeSignature(username, timestamp, secretKey));
return sb.toString();
}
public static boolean verifyToken(String token, String secretKey) throws InvalidKeyException, NoSuchAlgorithmException {
String[] parts = token.split(TOKEN_SEPARATOR);
boolean result = false;
if (parts.length == 3) {
String username = parts[0];
Long timestamp = Long.valueOf(parts[1]);
String signature = parts[2];
if (signature.equals(computeSignature(username, timestamp, secretKey))) {
if (System.currentTimeMillis() - timestamp < MAX_AGE) {
result = true;
}
}
}
return result;
}
private static String generateTokenStringPublicPart(String username, long timestamp) {
StringBuilder sb = new StringBuilder();
sb.append(username);
sb.append(TOKEN_SEPARATOR);
sb.append(timestamp);
return sb.toString();
}
private static String computeSignature(String username, long timestamp, String secretKey) throws InvalidKeyException, NoSuchAlgorithmException {
StringBuilder sb = new StringBuilder();
sb.append(generateTokenStringPublicPart(username, timestamp));
SecretKeySpec sks = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), HMAC_ALGO);
Mac hmac = Mac.getInstance(HMAC_ALGO);
hmac.init(sks);
return Base64.getUrlEncoder().encodeToString(hmac.doFinal(sb.toString().getBytes(StandardCharsets.UTF_8)));
}
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException {
String secretKey = "secret_key";
String token = TokenUtils.createToken("marko", System.currentTimeMillis(), secretKey);
System.out.println(token);
System.out.println("Original token verification: " + TokenUtils.verifyToken(token, secretKey));
token = token.replaceAll("a", "b");
System.out.println("Tampered token verification: " + TokenUtils.verifyToken(token, secretKey));
token = TokenUtils.createToken("marko", System.currentTimeMillis() - 1_000 * 60 * 60 * 48, secretKey);
System.out.println("Expired token verification: " + TokenUtils.verifyToken(token, secretKey));
}
}
关于java - 将 Joda 日期与用户名结合作为单个变量进行加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27039986/