常见加密算法以及安全级别和使用场景。
DES(安全级别不高,消耗性能 较小)
AES(安全级别较高)
MD5(安全级别较高,一般不用做加密,常用在校验文件)
RSA(安全级别特别高,消耗性能大)
SHA(不可解密,一般用在签名)
Aes工具类:
import javax.crypto.Cipher;import javax.crypto.spec.SecretKeySpec;import mons.codec.binary.Base64;import mons.codec.binary.Hex;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import cn.hutool.crypto.Mode;import cn.hutool.crypto.Padding;import cn.hutool.crypto.symmetric.AES;/*** Aes加解密*/public class AesUtil {private static final Logger logger = LogManager.getLogger("AESUtil");private static final String CHARSET = "UTF-8";public static String base64Encode(byte[] bytes) {return Base64.encodeBase64String(bytes);}public static byte[] base64Decode(String base64Code) throws Exception {return Base64.decodeBase64(base64Code.getBytes(CHARSET));}/*** 加密** @param content* @param encryptKey* @return* @throws Exception*/public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {initEncryptCipher(encryptKey);return encryptCipher.doFinal(content.getBytes(CHARSET));}/*** 加密** @param content* @param encryptKey* @return* @throws Exception*/public static byte[] aesEncryptToBytes(byte[] content, String encryptKey) throws Exception {initEncryptCipher(encryptKey);return encryptCipher.doFinal(content);}/*** 加密转字符** @param content* @param encryptKey* @return* @throws Exception*/public static String aesEncrypt(String content, String encryptKey) throws Exception {return base64Encode(aesEncryptToBytes(content, encryptKey));}/*** 解密** @param content* @param decryptKey* @return* @throws Exception*/public static byte[] aesDecryptByBytes(String content, String decryptKey) throws Exception {initDecryptCipher(decryptKey);return decryptCipher.doFinal(content.getBytes(CHARSET));}/*** 解密** @param content* @param decryptKey* @return* @throws Exception*/public static byte[] aesDecryptByBytes(byte[] content, String decryptKey) throws Exception {initDecryptCipher(decryptKey);return decryptCipher.doFinal(content);}public static String aesDecrypt(String content, String decryptKey) throws Exception {return new String(aesDecryptByBytes(base64Decode(content), decryptKey));}private static Cipher encryptCipher = null;private static Cipher decryptCipher = null;public static void initEncryptCipher(String aesKey) throws Exception {if (encryptCipher == null) {//5.根据字节数组生成AES密钥SecretKeySpec skeySpec = new SecretKeySpec(Hex.decodeHex(aesKey.toCharArray()), "AES");//6.根据指定算法AES自成密码器encryptCipher = Cipher.getInstance("AES");//7.初始化密码器encryptCipher.init(Cipher.ENCRYPT_MODE, skeySpec);}}public static void initDecryptCipher(String aesKey) throws Exception {if (decryptCipher == null) {//5.根据字节数组生成AES密钥SecretKeySpec skeySpec = new SecretKeySpec(Hex.decodeHex(aesKey.toCharArray()), "AES");//6.根据指定算法AES自成密码器decryptCipher = Cipher.getInstance("AES");//7.初始化密码器decryptCipher.init(Cipher.DECRYPT_MODE, skeySpec);}}public static String hutoolEncrpt(String content,String key){AES aes=new AES(Mode.ECB, Padding.ISO10126Padding, key.getBytes());return aes.encryptBase64(content);}public static String hutoolDecrpt(String content,String key){AES aes=new AES(Mode.ECB, Padding.ISO10126Padding, key.getBytes());return aes.decryptStr(content);}public static void main(String[] args) throws Exception {final String KEY = "2423424dsfsdfsdfdsfdsgfdfdfs4";String privateKeyStr = "管理员";String encrypt = aesEncrypt(privateKeyStr, KEY);logger.info("加密后:" + encrypt);String decrypt = aesDecrypt(encrypt, KEY);logger.info("解密后:" + decrypt);}}
Des3工具类:
import java.io.UnsupportedEncodingException;import java.nio.charset.StandardCharsets;import java.security.Key;import java.util.Base64;import javax.crypto.Cipher;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESedeKeySpec;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import org.bouncycastle.util.encoders.Hex;import cn.hutool.core.util.StrUtil;import lombok.extern.slf4j.Slf4j;@Slf4jpublic class Des3Utils {/*** 加密算法*/private static final String KEY_ALGORITHM = "DESede";private static final String CIPHER_ALGORITHM = "DESede/CBC/PKCS5Padding";/*** 3DES 加密* @param key 秘钥(24位)* @param iv 偏移量* @param data 需要加密的字符串* @return 返回加密的字符串*/public static String encrypt(String key, String iv, String data) {try {DESedeKeySpec spec = new DESedeKeySpec(key.getBytes(StandardCharsets.UTF_8));SecretKeyFactory keyfactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);Key deskey = keyfactory.generateSecret(spec);Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);IvParameterSpec ips = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);byte[] bOut = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));Base64.Encoder encoder = Base64.getMimeEncoder();return encoder.encodeToString(bOut);} catch (Exception e) {e.printStackTrace();log.error("3DES 解密错误:{}", e);throw new RuntimeException("3DES 解密错误");}}/*** 3DES 解密* @param key 秘钥(24位)* @param iv 偏移量* @param data 需要解密的密文* @return 返回加密的字符串*/public static String decrypt(String key, String iv, String data) {try {DESedeKeySpec spec = new DESedeKeySpec(key.getBytes(StandardCharsets.UTF_8));SecretKeyFactory keyfactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);Key deskey = keyfactory.generateSecret(spec);Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);IvParameterSpec ips = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));cipher.init(Cipher.DECRYPT_MODE, deskey, ips);byte[] bOut = cipher.doFinal(getBase64Decode(data));return new String(bOut, StandardCharsets.UTF_8);} catch (Exception e) {e.printStackTrace();log.error("3DES 解密错误:{}", e);throw new RuntimeException("3DES 解密错误");}}/*** * @param src* @param secretKey* @return*/public static String get3DESEncryptECB(String src, String secretKey) {try {Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");cipher.init(1, new SecretKeySpec(build3DesKey(secretKey), "DESede"));String base64Encode = getBase64Encode(cipher.doFinal(src.getBytes("UTF-8")));return filter(base64Encode);} catch (Exception var4) {return null;}}/*** * @param src* @param secretKey* @return*/public static String get3DESDecryptECB(String src, String secretKey) {try {Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");cipher.init(2, new SecretKeySpec(build3DesKey(secretKey), "DESede"));byte[] base64DValue = getBase64Decode(src);byte[] ciphertext = cipher.doFinal(base64DValue);return new String(ciphertext, "UTF-8");} catch (Exception var5) {return null;}}public static byte[] getBase64Decode(String str) {byte[] src = null;try {Base64.Decoder decoder = Base64.getMimeDecoder();src = decoder.decode(str);} catch (Exception var3) {var3.printStackTrace();}return src;}public static String getBase64Encode(byte[] src) {String requestValue = "";try {Base64.Encoder encoder = Base64.getMimeEncoder();requestValue = filter(encoder.encodeToString(src));} catch (Exception var3) {var3.printStackTrace();}return requestValue;}public static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException {byte[] key = new byte[24];byte[] temp = keyStr.getBytes("UTF-8");if (key.length > temp.length) {System.arraycopy(temp, 0, key, 0, temp.length);} else {System.arraycopy(temp, 0, key, 0, key.length);}return key;}private static String filter(String str) {String output = null;StringBuffer sb = new StringBuffer();for(int i = 0; i < str.length(); ++i) {int asc = str.charAt(i);if (asc != '\n' && asc != '\r') {sb.append(str.subSequence(i, i + 1));}}output = new String(sb);return output;}public static String byteToHexString(byte[] bytes) {StringBuffer sb = new StringBuffer();for(int i = 0; i < bytes.length; ++i) {String strHex = Integer.toHexString(bytes[i]);if (strHex.length() > 3) {sb.append(strHex.substring(6));} else if (strHex.length() < 2) {sb.append("0" + strHex);} else {sb.append(strHex);}}return sb.toString();}/*** 将data中的密文Hex后3DES解码* @param content* @param key* @return*/public static String reHexAndDecrypt(String content, String key) {if(StrUtil.isBlank(content)) {return null;}byte[] hexBytes = Hex.decode(content.getBytes(StandardCharsets.UTF_8));String baseReqStr = getBase64Encode(hexBytes);String outInfo = Des3Utils.get3DESDecryptECB(baseReqStr, key);return outInfo;}}
MD5工具类
import java.nio.charset.StandardCharsets;import java.security.MessageDigest;import mon.util.ByteUtil;import mon.util.ErrorUtil;import lombok.extern.slf4j.Slf4j;/*** MD5 工具类*/@Slf4jpublic class MD5Util {/*** 生成MD5加密串*/public static String getMd5(String message) {String md5 = "";try {//创建一个md5算法对象MessageDigest md = MessageDigest.getInstance("MD5");byte[] messageByte = message.getBytes(StandardCharsets.UTF_8);//获得MD5字节数组,16*8=128位byte[] md5Byte = md.digest(messageByte);//转换为16进制字符串md5 = ByteUtil.bytesToHex(md5Byte);} catch (Exception e) {//输出到日志文件中log.error(ErrorUtil.errorInfoToString(e));}return md5;}/*** 验证方法* @param text 明文* @param md5 密文* @return 对比结果*/private static boolean verify(String text,String md5){return md5.equals(getMd5(text));}public static void main(String[] args) {System.out.print(MD5Util.getMd5("maoheyere@cn"));}}
RSA工具类
import cn.hutool.jwt.JWTUtil;import mons.codec.binary.Base64;import mons.lang.ArrayUtils;import javax.crypto.Cipher;import java.security.*;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;import java.util.Map;/*** RSA加解密*/public class RsaUtils {/*** RSA最大加密明文大小*/private static final int MAX_ENCRYPT_BLOCK = 117;/*** RSA最大解密密文大小*/private static final int MAX_DECRYPT_BLOCK = 128;public static final String SIGN_ALGORITHMS = "SHA256withRSA";private static String ALGORITHM_RSA = "RSA";/*** 私钥加签名* @param encryptData* @param privateKey* @return*/public static String rsaSign(String encryptData, String privateKey) {try {Signature signature = Signature.getInstance(SIGN_ALGORITHMS);signature.initSign(loadPrivateKey(privateKey));signature.update(encryptData.getBytes());byte[] signed = signature.sign();return Base64.encodeBase64URLSafeString(signed);} catch (Exception e) {e.printStackTrace();}return null;}/*** 公钥验签* @param encryptStr* @param sign* @param publicKey* @return* @throws Exception*/public static boolean verifySign(String encryptStr, String sign, String publicKey)throws Exception {try {Signature signature = Signature.getInstance(SIGN_ALGORITHMS);signature.initVerify(loadPublicKey(publicKey));signature.update(encryptStr.getBytes());return signature.verify(Base64.decodeBase64(sign));} catch (NoSuchAlgorithmException e) {throw new Exception(String.format("验证数字签名时没有[%s]此类算法", SIGN_ALGORITHMS));} catch (InvalidKeyException e) {throw new Exception("验证数字签名时公钥无效");} catch (SignatureException e) {throw new Exception("验证数字签名时出现异常");}}public static PublicKey loadPublicKey(String publicKeyStr) throws Exception {byte[] buffer = Base64.decodeBase64(publicKeyStr);KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);return keyFactory.generatePublic(keySpec);}public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception {byte[] buffer = Base64.decodeBase64(privateKeyStr);PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);return keyFactory.generatePrivate(keySpec);}/*** @Description RSA解密*/protected static String rsaEncrypt(String sourceData, String key,boolean isPrivate){try {Key key1 = isPrivate ? loadPrivateKey(key) : loadPublicKey(key);byte[] data = sourceData.getBytes();byte[] dataReturn = new byte[0];Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);cipher.init(Cipher.ENCRYPT_MODE, key1);// 加密时超过117字节就报错。为此采用分段加密的办法来加密StringBuilder sb = new StringBuilder();for (int i = 0; i < data.length; i += MAX_ENCRYPT_BLOCK) {byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i,i + MAX_ENCRYPT_BLOCK));sb.append(new String(doFinal));dataReturn = ArrayUtils.addAll(dataReturn, doFinal);}return Base64.encodeBase64URLSafeString(dataReturn);} catch (Exception e) {e.printStackTrace();return null;}}/*** @Description RSA解密*/protected static String rsaDecrypt(String encryptedData, String key,boolean isPrivate){try {Key key1 = isPrivate ? loadPrivateKey(key) : loadPublicKey(key);byte[] data = Base64.decodeBase64(encryptedData);Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);cipher.init(Cipher.DECRYPT_MODE, key1);// 解密时超过128字节就报错。为此采用分段解密的办法来解密byte[] dataReturn = new byte[0];for (int i = 0; i < data.length; i += MAX_DECRYPT_BLOCK) {byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + MAX_DECRYPT_BLOCK));dataReturn = ArrayUtils.addAll(dataReturn, doFinal);}return new String(dataReturn);} catch (Exception e) {e.printStackTrace();return null;}}/*** 使用公钥将数据加密* @param sourceData* @param publicKey* @return*/public static String publicEncrypt(String sourceData, String publicKey){return rsaEncrypt(sourceData,publicKey,false);}/*** 使用私钥将数据加密* @param sourceData* @param privateKey* @return*/public static String privateEncrypt(String sourceData, String privateKey){return rsaEncrypt(sourceData,privateKey,true);}/*** 使用公钥解密* @param encryptedData* @param privateKey* @return*/public static String publicDecrypt(String encryptedData, String privateKey) {return rsaDecrypt(encryptedData,privateKey,false);}/*** 使用私钥解密* @param encryptedData* @param privateKey* @return*/public static String privateDecrypt(String encryptedData, String privateKey) {return rsaDecrypt(encryptedData,privateKey,true);}public static void main(String[] args) {String password = "123456";Map<String,Object> map=new HashMap<>();map.put("user_id","5353453453");map.put("sessionKey","123553444");String message = JWTUtil.createToken(map, password.getBytes());try {String publicKeyStr = "MIGfMA0GCSqGSIb3DQEHHQUAA4GNADCBiQKBgQC6BSDlbRplhMMNZBKHX4xe8AwE" +"SpzHVfAcHHsX9FFSMuF91W3cxgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKw" +"ko3tK9Ua691afod1lxORR3IaZ8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41G" +"qvOw3G9leClSvjVnSwIDAQAB";String privateKeyStr = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALoFIOVtGmWEww1k" +"EodfjF7wDARKnMdV8Bwcexf0UVIy4X3VbdzGBP+Dmf6qUssXMITeFYb/Jfk0wDFH" +"iZLcyWHJcrCSje0r1Rrr3Vp+h3WXE5FHchpnydXu/kG/zLgkN7gTf9/9tAgbOuha" +"InSxdNw7jUaq87dsb2V4KVK+NWdLAgMBAAECgYBqCihhgJtOiarjBEvnrZkIOZCw" +"FZRfsWaJr9afph+BWw3dvH+/HYaV3YA4gwFlUlfPNgZRiTstX1u7+8q51HBa+08h" +"jPE8Q4GhoUY+sQ9MB8NXA6SWHNPPfMOYIeKEtKmNBdgIbtuhnob3o18rJNFIY+qC" +"i8djf4om93+AChmo6QJBAO31hd9qem7BnHXsxiMwS+iHlRjW9KxXva2zf+BNURSR" +"Z19cePReHJGE4v1C731MZlygTB5zKChQ8uZ3JLKJeX8CQQDIH4k/xbuhMb8dMdzl" +"AYN/CU+MgfWjlgbYjxOnTaLcbs5Mlz9v3/5I/FwqxPvzGuCjHkyh08oFfnQXvzdj" +"YMA1AkEApjgyOnzzZvisdXJueVgcPiKvSHmm0dg8W+Cd+72mXHqxPdCngPNYe2Ha" +"+VRPXDQI8LzcTwzbyUW6Vrh0/u2+2wJBAK1rZqx01VuimFLcWue4oBL+JolENXFF" +"GTmhAw8AIBmVjACjML3qBZmJ1vTZLtxEdlXkc9PojDCmnEPX2E+uD+ECQF2eX4EY" +"X95HDzQ4cm1kGQudjgfH1gZ+30DIingfHXNAOFpYeAUD7yUQP5tZO8nG38gybPJg" +"FoadlsSMIQIpksM=";//加密String privateEncryptStr = privateEncrypt(message, privateKeyStr);String publicEncryptStr = publicEncrypt(message, publicKeyStr);String privateEncryptSign = rsaSign(privateEncryptStr,privateKeyStr);String publicEncryptSign = rsaSign(publicEncryptStr,privateKeyStr);System.out.println("source:" + message);System.out.println("private encryptStr: " + privateEncryptStr);System.out.println("public encryptStr: " + publicEncryptStr);System.out.println("private encrypt sign: " + privateEncryptSign);System.out.println("public encrypt sign: " + publicEncryptSign);System.out.println("public decrypt:" + publicDecrypt(privateEncryptStr, publicKeyStr));System.out.println("private decrypt:" + privateDecrypt(publicEncryptStr, privateKeyStr));System.out.println("verifySign1: " + verifySign(privateEncryptStr,privateEncryptSign,publicKeyStr));System.out.println("verifySign2: " + verifySign(publicEncryptStr,publicEncryptSign,publicKeyStr));} catch (Exception e) {e.printStackTrace();}}}
SHA_1工具类
import java.security.MessageDigest;import java.util.Base64;/*** SHA非对称加密算法(不可解密)*/public class SHAUtils {// ASC 加密秘钥/*** SHA非对称加密算法* * @param spara* @return*/public static String getSHA(String spara) {String sRtn = null;try {byte[] plainText = spara.getBytes("UTF8");// 使用getInstance("算法")来获得消息摘要,这里使用SHA-1的160位算法MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");// 开始使用算法messageDigest.update(plainText);// 输出算法运算结果Base64.Encoder encoder = Base64.getMimeEncoder();sRtn = encoder.encodeToString(messageDigest.digest());//sRtn = new BASE64Encoder().encode(messageDigest.digest());} catch (Exception e) {e.printStackTrace();}return sRtn;}// 测试public static void main(String[] args) throws Exception {String sourceStr = "86-15013658624";String s = getSHA(sourceStr);System.out.println(s);}}
token工具类
import cn.lzscxb.entity.exception.ConditionException;import com.auth0.jwt.JWT;import com.auth0.jwt.JWTVerifier;import com.auth0.jwt.algorithms.Algorithm;import com.auth0.jwt.exceptions.SignatureVerificationException;import com.auth0.jwt.exceptions.TokenExpiredException;import com.auth0.jwt.interfaces.Claim;import com.auth0.jwt.interfaces.DecodedJWT;import lombok.extern.slf4j.Slf4j;import java.util.Calendar;import java.util.Date;import java.util.Map;@Slf4jpublic class TokenUtils {private static final String ISSUER = "";private static final Integer EXPIRE =30 ;/*** 生成token** @param userId* @return* @throws Exception*/public static String generateToken(Long userId, String phone, String avatar, String nickname) {Algorithm algorithm = null;try {algorithm = Algorithm.RSA256(RSAUtils.getPublicKey(), RSAUtils.getPrivateKey());} catch (Exception e) {throw new RuntimeException(e);}Calendar calendar = Calendar.getInstance(); // 日历类用于生成过期时间calendar.setTime(new Date());calendar.add(Calendar.SECOND, EXPIRE);return JWT.create().withKeyId(String.valueOf(userId)).withIssuer(ISSUER).withExpiresAt(calendar.getTime()).withClaim("user_id", userId).withClaim("phone", phone).withClaim("avatar", avatar).withClaim("nickname", nickname).sign(algorithm);}public static Map<String, Claim> VerifyToken(String token) {try {Algorithm algorithm = Algorithm.RSA256(RSAUtils.getPublicKey(), RSAUtils.getPrivateKey());JWTVerifier verifier = JWT.require(algorithm).build();DecodedJWT jwt = verifier.verify(token);Map<String, Claim> claims = jwt.getClaims();return claims;} catch (TokenExpiredException e) {throw new ConditionException(401, "token 令牌已过期");} catch (SignatureVerificationException e) {e.printStackTrace();log.info(token);throw new ConditionException(401, "token 令牌无效");} catch (Exception e) {throw new RuntimeException(e);}}}
如果觉得《JAVA架构之路(数据加密与常见加密算法)》对你有帮助,请点赞、收藏,并留下你的观点哦!