赞
踩
相关概念:
所谓对称就是指加密和解密都是使用同一个钥匙(密钥)
例如:
①小明要传递一个信息A给小红:A + B = C(小明通过对信息A进行加密后,得到信息C传给小红)
②小红拿到信息C后,C - B = A(小红拿到数据后,用密钥B进行解密,得到初始信息A)
特点:
算法公开、加密和解密速度快,适合对大数据量进行加密;但是与非对称加密相比,安全性降低
非对称加密也要公钥加密。与对称加密相比,安全性更好。对称加密的通信双方使用相同的秘钥,如果任意一方的密钥被泄露,整个通信就会被破解。
非对称加密使用的是一对密钥,即公钥和私钥,且二者成对出现。私钥被自己保存,不能对外泄露。公钥指的是公共的密钥,任何人都可以获得该密钥。用公钥或私钥中的任何一个进行加密,用另一个进行解密。
过程:
明文 + 加密算法 + 公钥 = 密文; 密文 + 解密算法 + 私钥 = 明文
例子:
加密算法分为:对称加密和非对称加密【此外还有一类不需要密钥的散列算法】
常见的对称加密算法:DES、3DES、AES、HS256
常见的非对称加密算法:RSA、DSA
散列算法:SHA-1、MD5
见文章:
https://blog.csdn.net/weixin_45565886/article/details/126557256?spm=1001.2014.3001.5501
企业中开发代码:
package com.zi.api.commons.util; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import io.jsonwebtoken.*; import javax.crypto.spec.SecretKeySpec; import javax.xml.bind.DatatypeConverter; import java.security.Key; import java.util.HashMap; import java.util.Map; /** * 生成jwt工具类 */ public class JJWTRootUtils { //定义对应的编码算法 static SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; //盐值 static String secretKey = "d8de020f63754a9fa746ea74b831afc3"; //获取key(指定算法和盐值的key对象) private static Key generateKey(){ //将盐值转成字节 byte[] bytes = DatatypeConverter.parseBase64Binary(secretKey); //根据算法和盐值生成对应的key值 Key key = new SecretKeySpec(bytes, signatureAlgorithm.getJcaName()); return key; } /** * 将我们的数据使用JWT的方式变成一个token xxx.yyy.zzz * @param payLoad 负载(数据信息) * @return */ public static String generatorToken(Map<String, String> payLoad){ ObjectMapper objectMapper = new ObjectMapper(); try{ //构建jwt生成器 JwtBuilder builder = Jwts.builder(); //将负载信息设置到jwt生成器中 JwtBuilder jwtBuilder = builder.setPayload(objectMapper.writeValueAsString(payLoad)); //根据签名算法和key值,生成新的jwtBuilder JwtBuilder jwtBuilder1 = jwtBuilder.signWith(signatureAlgorithm, generateKey()); String token = jwtBuilder1.compact(); return token; } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } /** * 根据指定的token, 返回对应的body信息 * @param token * @return */ public static Claims phaseTokenGetBody(String token){ JwtParser jwtParser = Jwts.parser().setSigningKey(generateKey()); Jws<Claims> claimsJws = jwtParser.parseClaimsJws(token); Claims body = claimsJws.getBody();//主要存放的信息 return body; } /** * 根据指定的token获取签名信息 * @param token * @return */ public static String phaseTokenGetSignature(String token){ JwtParser jwtParser = Jwts.parser().setSigningKey(generateKey()); Jws<Claims> claimsJws = jwtParser.parseClaimsJws(token); String signature = claimsJws.getSignature(); return signature; } /** * 根据指定的token获取头信息 * @param token * @return */ public static JwsHeader phaseTokenGetHeader(String token){ //获取解析器 JwtParser parser = Jwts.parser(); //设置签名key(盐值) parser = parser.setSigningKey(generateKey()); //解析token Jws<Claims> claimsJws = parser.parseClaimsJws(token); JwsHeader header = claimsJws.getHeader(); return header; } public static void main(String[] args) { //随机获取盐值 // System.out.println(UUID.randomUUID().toString().replaceAll("-", "")); Map<String, String> payLoad = new HashMap<>(); payLoad.put("name", "curry"); String s = generatorToken(payLoad); //eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiY3VycnkifQ.Sf3GiF3p56nLzoAxEHLXcAckPmmPTtecj1_lGT9oV8s System.out.println(s); //调用自定义API获取结果 Claims claims = phaseTokenGetBody(s); //{name=curry} System.out.println(claims); } }
RSA算法
RSA算法 的保密强度随其密钥的长度增加而增强。但是,密钥越长,其加解密所耗用的时间也越长。
首先编写RSAUtil工具类,用于生成RSA的公钥私钥
//RSA是一种非对称加密算法【公钥、私钥】 public class RASUtil { /** * 生成一对公私钥 */ public static void generatorKey() throws NoSuchAlgorithmException { //构建一个生成公私钥 RAS算法生成的对象 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); //初始化生成器 keySize:512起 keyPairGenerator.initialize(512, new SecureRandom()); //密钥对 KeyPair keyPair = keyPairGenerator.generateKeyPair(); //获取私钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); //获取公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); //获取私钥字符串 String privateKeyStr = new String(Base64.encodeBase64(privateKey.getEncoded())); String publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded())); System.out.println("privateKeyStr:" + privateKeyStr); System.out.println("publicKeyStr:" + publicKeyStr); //privateKeyStr:MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAhUfkmkFtrOlFiX8FmHiYx9mAPpfTA6oKE6VgFLDNQzYO1YMugA0ACChp6n3hfDWOp3XgWWRVmzU+z30h+01lyQIDAQABAkBtvjvKlDNFnDJou9GUsUBD1qDVaVgT/VAcyyApCUeKnehPLMISa5JBTUpJ03cMPh3hV7q4OJQweM7nuJ+GXcCBAiEAx5xHdUM3XnFZ6aQnAvKzPWqV/eqpDRj9aSFiR/vbJ3kCIQCq7rDN2qs1DUo8XS2WcbBOFLMU+uHDuV8rigFe0yyM0QIgfQ5hCotRDh9P6HwKYONy/kBftlQlE2qboRjkPRsCQ2kCIBUoVlokpux6KKYwImRszhXcGg6Ov0Mqvsz02BaUrP8BAiBrxV/0jPm2pr3GJXW5MHhJ4a2LrkYFfWdHQx+gpSJESg== //publicKeyStr:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIVH5JpBbazpRYl/BZh4mMfZgD6X0wOqChOlYBSwzUM2DtWDLoANAAgoaep94Xw1jqd14FlkVZs1Ps99IftNZckCAwEAAQ== } public static void main(String[] args) throws NoSuchAlgorithmException { generatorKey(); } }
注意:企业中工具类中一般是没有main方法的,此处只是为了方便测试
一般包含方法:
/** * 根据RSA算法加密生成token * @param payload * @return */ public static String genTokenRAS(Map<String, String> payload){ //指定过期时间 【3天】 Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DATE, 3); //获取一个构建对象【静态内部类】 JWTCreator.Builder builder = JWT.create(); //将信息、数据(body)信息放到需要的claim里面 payload.forEach((k, v) -> builder.withClaim(k, v)); //通过hutool工具类来创建RSA对象 RSA rsa = new RSA(PRIVATE_KEY_STR, null); //获取私钥 RSAPrivateKey privateKey = (RSAPrivateKey) rsa.getPrivateKey(); String token = builder.withExpiresAt(calendar.getTime()).sign(Algorithm.RSA256(null, privateKey)); return token; }
/** * 使用RSA的方式来解密 * @param token * @return * 根据不同的异常来判断当前token到底是什么情况 */ public static DecodedJWT decodedRSA(String token){ //通过公钥获取我们的RSA的公钥对象 RSA rsa = new RSA(null, PUBLIC_KEY_STR); RSAPublicKey publicKey = (RSAPublicKey) rsa.getPublicKey(); //jwt的验证对象 JWTVerifier jwtVerifier = JWT.require(Algorithm.RSA256(publicKey, null)).build(); DecodedJWT decodedJWT = jwtVerifier.verify(token); return decodedJWT; }
private static final String SECRET = "H2OJ20FC35APACHE";
/** * 获取token * @param payload * @return */ public static String getToken(Map<String, String> payload){ //指定过期时间【3天】 Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DATE, 3); //获取一个构建对象【静态内部类】 JWTCreator.Builder builder = JWT.create(); //将body信息放到我们需要生成的claim里面 payload.forEach((k, v) -> builder.withClaim(k, v)); //通过指定签名算法和过期时间生成一个token String token = builder.withExpiresAt(calendar.getTime()).sign(Algorithm.HMAC256(SECRET)); return token; }
/**
* 解析token
* @param token
* @return
*/
public static DecodedJWT decodedJWT(String token){
//构建一个验证jwt token的对象
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
//验证以后获取信息的对象
DecodedJWT decodedJWT = jwtVerifier.verify(token);
//返回信息对象
return decodedJWT;
}
package com.zi.api.commons.util; import cn.hutool.crypto.asymmetric.RSA; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTCreator; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.DecodedJWT; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.Calendar; import java.util.HashMap; import java.util.Map; /** * 加密解密token */ public class JWTAuth0Util { private static final String SECRET = "H2OJ20FC35APACHE"; //私钥和公钥 private static final String PRIVATE_KEY_STR = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAjX+A8rA2a8tJNQ2DK5pnfaXqHyv5iSG2KdWJk3GMkfN0VuEO/JvbM0ljQgi6/qPmgUIFgL65meavzJXDMr8IZQIDAQABAkEAh7JZdWRsLGAd6tT0kGJZEXSF3DMN8eb0jZYNg+sHRgdovJtlHZBTiMbSoQphvsYe8dBHplOjktzTipTe0y/rmQIhAMP13C1UFEPdFv9D6mFg+hehr0Jk+vcxOoGFA1o0vOz/AiEAuNnk/2etuErfNdgN9ujc88TAG2mpzBvyxpIHNQridpsCIC44dYBzjnwbT+tRt5zUZOjiCBae/tsDT4txNkM2oUE9AiBoN4jxKi36KlRAEiiFXXI9CV9Z1S/DALrWkzv2/sUBIwIgXgMe3SW4vML/ieQHIEmk+GhDD/NJad9Hs4HOBkNcA1I="; private static final String PUBLIC_KEY_STR = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAI1/gPKwNmvLSTUNgyuaZ32l6h8r+YkhtinViZNxjJHzdFbhDvyb2zNJY0IIuv6j5oFCBYC+uZnmr8yVwzK/CGUCAwEAAQ=="; /** * 根据RSA算法加密生成token【非对称】 * @param payload * @return */ public static String genTokenRAS(Map<String, String> payload){ //指定过期时间 【3天】 Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DATE, 3); //获取一个构建对象【静态内部类】 JWTCreator.Builder builder = JWT.create(); //将信息、数据(body)信息放到需要的claim里面 payload.forEach((k, v) -> builder.withClaim(k, v)); //通过hutool工具类来创建RSA对象 RSA rsa = new RSA(PRIVATE_KEY_STR, null); //获取私钥 RSAPrivateKey privateKey = (RSAPrivateKey) rsa.getPrivateKey(); String token = builder.withExpiresAt(calendar.getTime()).sign(Algorithm.RSA256(null, privateKey)); return token; } /** * 使用RSA的方式来解密【非对称】 * @param token * @return * 根据不同的异常来判断当前token到底是什么情况【比如被伪造...】 */ public static DecodedJWT decodedRSA(String token){ //通过公钥获取我们的RSA的公钥对象 RSA rsa = new RSA(null, PUBLIC_KEY_STR); RSAPublicKey publicKey = (RSAPublicKey) rsa.getPublicKey(); //jwt的验证对象 JWTVerifier jwtVerifier = JWT.require(Algorithm.RSA256(publicKey, null)).build(); DecodedJWT decodedJWT = jwtVerifier.verify(token); return decodedJWT; } /** * 获取token【对称加密】 * @param payload * @return */ public static String getToken(Map<String, String> payload){ //指定过期时间【3天】 Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DATE, 3); //获取一个构建对象【静态内部类】 JWTCreator.Builder builder = JWT.create(); //将body信息放到我们需要生成的claim里面 payload.forEach((k, v) -> builder.withClaim(k, v)); //通过指定签名算法和过期时间生成一个token String token = builder.withExpiresAt(calendar.getTime()).sign(Algorithm.HMAC256(SECRET)); return token; } /** * 解析token【对称加密】 * @param token * @return */ public static DecodedJWT decodedJWT(String token){ //构建一个验证jwt token的对象 JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET)).build(); //验证以后获取信息的对象 DecodedJWT decodedJWT = jwtVerifier.verify(token); //返回信息对象 return decodedJWT; } public static void main(String[] args) { Map<String, String> map = new HashMap<>(); map.put("helicopter", "apache"); String rsaCodeStr = genTokenRAS(map); System.out.println("非对称加密后的token:" + rsaCodeStr); DecodedJWT decodedJWT = decodedRSA(rsaCodeStr); String rsaDecodeStr = decodedJWT.getToken(); System.out.println("非对称解密后的token:" + rsaDecodeStr); String hmacCodeStr = getToken(map); System.out.println("对称加密后的token:" + hmacCodeStr); DecodedJWT decodedJWT1 = decodedJWT(hmacCodeStr); String hmacDeCodeStr = decodedJWT1.getToken(); System.out.println("对称解密后的token:" + hmacDeCodeStr); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。