public class EncodePassword { // (1)加密算法有:AES,DES,DESede(DES3)和RSA 四种 // (2) 模式有CBC(有向量模式)和ECB(无向量模式),向量模式可以简单理解为偏移量,使用CBC模式需要定义一个IvParameterSpec对象 // (3) 填充模式: // * NoPadding: 加密内容不足8位用0补足8位, Cipher类不提供补位功能, // 需自己实现代码给加密内容添加0, 如{65,65,65,0,0,0,0,0} // * PKCS5Padding: 加密内容不足8位用余位数补足8位, // 如{65,65,65,5,5,5,5,5}或{97,97,97,97,97,97,2,2}; 刚好8位补8位8 // private static final String ENCODE_TYPE = "AES/CBC/PKCS5Padding"; "算法/模式/填充模式" //指定算法 private static final String ENCODE_TYPE = "AES"; //salt 盐值 , 用于生成密钥 private static final String publicKey = "s7WKkt@zqJO+wVdW"; public static void main(String[] args) throws Exception { getSecretKey(); System.out.println("============AES对称加密方式================"); String aesEncode = testAESEncode("wo6ai8zhong6guo"); // 加密后的密码 String aesDecode = testAESDecode(publicKey, aesEncode); System.out.println("解密后的密码:"+aesDecode); // System.out.println("============Base64提供的加密方式(可逆)================"); // testBase64Encode(); // System.out.println("============spring-security-core提供的加密方式================"); // testBCryptEncode(); } // 生成密钥 private static void getSecretKey() throws NoSuchAlgorithmException { // 通过 KeyGenerator创建秘密密匙 128、192和256位 KeyGenerator keyGenerator = KeyGenerator.getInstance(ENCODE_TYPE); keyGenerator.init(128); SecretKey keySpec = keyGenerator.generateKey(); byte[] encoded = keySpec.getEncoded(); //密钥 String str = Base64.getEncoder().encodeToString(encoded); System.out.println("KeyGenerator:"+str); SecretKey secretKey = new SecretKeySpec(publicKey.getBytes(), ENCODE_TYPE); byte[] encoded1 = secretKey.getEncoded(); System.out.println(encoded1.toString()); String str1 = Base64.getEncoder().encodeToString(encoded1); System.out.println("SecretKeySpec:"+str1); } /* AES加密数据块和密钥长度可以是128比特、192比特、256比特中的任意一个。 AES是一种对称的加密算法,可基于相同的密钥进行加密和解密。 Java采用AES算法进行加解密的逻辑大致如下: 1、生成/获取密钥 2、加/解密 密钥的生成可通过KeyGenerator来生成。 通过获取一个KeyGenerator实例,然后调用其generateKey()方法即可生成一个SecretKey对象。 可以使用SecretKeySpec、KeyGenerator和KeyPairGenerator创建密匙 * SecretKeySpec和KeyGenerator支持AES,DES,DESede三种加密算法创建密匙 * KeyPairGenerator支持RSA加密算法创建密匙 */ //AES密码加密 并使用base64 转化为String 类型 private static String testAESEncode(String password) throws Exception { // 通过 SecretKeySpec 创建 秘密密匙 Cipher cipher = Cipher.getInstance(ENCODE_TYPE); SecretKey secretKey = new SecretKeySpec(publicKey.getBytes(), ENCODE_TYPE); cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] encrypted = cipher.doFinal(password.getBytes()); String pwdEncode = Base64.getEncoder().encodeToString(encrypted); return pwdEncode; } //aes解密 private static String testAESDecode(String publicKey, String passwordBaseEncode) throws Exception { byte[] aesEncodePwd = Base64.getDecoder().decode(passwordBaseEncode); Cipher cipher = Cipher.getInstance(ENCODE_TYPE); SecretKey secretKey = new SecretKeySpec(publicKey.getBytes(), ENCODE_TYPE); cipher.init(Cipher.DECRYPT_MODE,secretKey); byte[] encrypted = cipher.doFinal(aesEncodePwd); String password = new String(encrypted); return password; } // Base64加密 private static void testBase64Encode() { Base64.Encoder encoder = Base64.getEncoder(); String encodePassword = encoder.encodeToString("7B8BC5D71C4C7B174C08EE4D42E1B5F8".getBytes()); System.out.println(encodePassword); //生产4个随机字母 String random = RandomStringUtils.randomAlphabetic(4); String randoms = random+encodePassword;//进行拼接 System.out.println(randoms); Base64.Decoder decoder = Base64.getDecoder(); String decodePassword = new String(decoder.decode(randoms.substring(4))); System.out.println(decodePassword); } // BCrypt 加密 需要导入包 /** * <dependency> * <groupId>org.springframework.security</groupId> * <artifactId>spring-security-core</artifactId> * <version>5.3.4.RELEASE</version> * </dependency> */ private static void testBCryptEncode() { BCryptPasswordEncoder bcryEncoder = new BCryptPasswordEncoder(); //密码加密 String encode = bcryEncoder.encode("7B8BC5D71C4C7B174C08EE4D42E1B5F8"); System.out.println(encode); //验证密码是否正确 内部实现, 没有提供解码的方法 boolean matches = bcryEncoder.matches("7B8BC5D71C4C7B174C08EE4D42E1B5F8", encode); System.out.println(matches); }
/**
* msg: 加密的内容; secretKey: 规定的密钥
*/
private static String hmacSHA256(String msg, String secretKey) {
try {
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), algorithm);
Mac mac = Mac.getInstance(algorithm);
mac.init(keySpec);
byte[] signatureBytes = mac.doFinal(postBody.getBytes(StandardCharsets.UTF_8));
StringBuilder signatureBuilder = new StringBuilder();
for (byte b : signatureBytes) {
String hex = Integer.toHexString(0xFF & b);
if (hex.length() == 1) {
signatureBuilder.append('0');
}
signatureBuilder.append(hex);
}
return signatureBuilder.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Md5Utils {
private static final int HEX_VALUE_COUNT = 16;
public static String getMD5(byte[] bytes) {
char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
char[] str = new char[16 * 2];
try {
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
md.update(bytes);
byte[] tmp = md.digest();
int k = 0;
for (int i = 0; i < HEX_VALUE_COUNT; i++) {
byte byte0 = tmp[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
} catch (Exception e) {
e.printStackTrace();
}
return new String(str);
}
public static String getMD5(String value, String encode) {
String result = "";
try {
result = getMD5(value.getBytes(encode));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
}
JWT生成令牌:
<!-- jwt依赖包开始 --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.4.0</version> </dependency>
/**
* 签发JWT
* @param id 可以设置为登录账户的ID
* @param subject 可以是JSON数据,如登录用户的JSON字符串 尽可能少
* @return
*/
public static String signToken(String id, String subject) {
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
JwtBuilder builder = Jwts.builder()
.setId(id)
.setSubject(subject) // 主题
.setIssuer("admin") // 签发者
.setIssuedAt(now) // 签发时间
.signWith(SignatureAlgorithm.HS256,'盐'); // 签名算法以及密匙
long expMillis = nowMillis + "过期时间";
Date expDate = new Date(expMillis);
builder.setExpiration(expDate); // 过期时间
return builder.compact();
}