加密算法
md5加密
md5是一种单向加密算法,只能加密无法解密
public static void main(String[] args) { try { //获取一个加密算法的实例 MessageDigest md = MessageDigest.getInstance("MD5"); String password = "zs123123"; //密码是字符串不能进行运算,因此需要将字符串转换为可以运算的数值类型 byte[] bytes = password.getBytes(); //进行加密运算,但加密运算后,数组中的元素值就发生了变化,不一定再为正数 byte[] result = md.digest(bytes); //使用BASE64编码器对加密结果进行编码处理,将所有的元素值转换为正数后再转换成字符串显示 String s = Base64.getEncoder().encodeToString(result); } catch (Exception e) { throw new RuntimeException(e); } }
但是md5有被暴力破解的可能性,因此需要再此基础上加一道关卡,即随机盐。
//生成随机数 public static String randomStr(int length){ StringBuilder sb = new StringBuilder(); for (int i = 0; i < length; i++) { //在CHARS数组长度范围内取一个随机数 int index = RANDOM.nextInt(CHARS.length); char c = CHARS[index]; if(index % 2 ==0){ sb.append(c); } else { sb.append(Character.toUpperCase(c)); } } return sb.toString(); }
将随机盐和密码进行整合,生成新的字符串再进行加密和编码:
public static void main(String[] args) { try { //获取一个加密算法的实例 MessageDigest md = MessageDigest.getInstance("MD5"); String password = "zs123123"; //生成一个10位的随机盐,主要用于提升密码的安全性 String salt = randomStr(10); int half1 = password.length() / 2; int half2 = salt.length() / 2; String newStr = password.substring(0,half1) + salt.substring(0,half2) + password.substring(half1) + salt.substring(half2); //密码是字符串不能进行运算,因此需要将字符串转换为可以运算的数值类型 byte[] bytes = newStr.getBytes(); //进行加密运算,但加密运算后,数组中的元素值就发生了变化,不一定再为正数 byte[] result = md.digest(bytes); //使用BASE64编码器对加密结果进行编码处理,将所有的元素值转换为正数后再转换成字符串显示 String s = Base64.getEncoder().encodeToString(result); } catch (Exception e) { throw new RuntimeException(e); } }
这样就算被暴力破解得到原字符串,也不知道随机盐以及随机盐和原密码是如何组合的,因此无法得知原密码。
这只是一种简单的md5加密算法。
抽取出成为方法:
/** * md5加密算法 * @param source 待加密的字符串 * @param salt 随机盐 * @return */ public static String md5(String source,String salt){ try { //获取一个加密算法的实例 MessageDigest md = MessageDigest.getInstance("MD5"); //生成一个10位的随机盐,主要用于提升密码的安全性 int half1 = source.length() / 2; int half2 = salt.length() / 2; String newStr = source.substring(0,half1) + salt.substring(0,half2) + source.substring(half1) + salt.substring(half2); //密码是字符串不能进行运算,因此需要将字符串转换为可以运算的数值类型 byte[] bytes = newStr.getBytes(); //进行加密运算,但加密运算后,数组中的元素值就发生了变化,不一定再为正数 byte[] result = md.digest(bytes); //使用BASE64编码器对加密结果进行编码处理,将所有的元素值转换为正数后再转换成字符串显示 String s = Base64.getEncoder().encodeToString(result); return s; } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } }
RSA非对称加密
使用密钥对来进行加密和解密
public static void main(String[] args) { //RSA 非对称加密算法 => 使用密钥对来进行加密和解密 try { String seed = "zhangSan"; //获取一个RSA加密算法的密钥对生成器 KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); //初始化密钥对生成器的秘钥大小为512,使用的随机安全种子为seed generator.initialize(512,new SecureRandom(seed.getBytes())); //密钥对生成器生成密钥对 KeyPair keyPair = generator.genKeyPair(); //获取公钥,用来加密 PublicKey publicKey = keyPair.getPublic(); //获取私钥,用来解密 PrivateKey privateKey = keyPair.getPrivate(); //获取一个RSA加密器/解密器实例 Cipher cipher = Cipher.getInstance("RSA"); //加密器初始化,当前模式为加密模式,使用的秘钥为公钥 cipher.init(Cipher.ENCRYPT_MODE,publicKey); //加密器对数据进行加密处理 byte[] result = cipher.doFinal("123123zs".getBytes()); String s = Base64.getEncoder().encodeToString(result); System.out.println(s); //解密器初始化,当前模式为解密模式,使用的秘钥为私钥 cipher.init(Cipher.DECRYPT_MODE,privateKey); //需要将之前进行编码处理的数据进行还原 byte[] data = Base64.getDecoder().decode(s); //解密器对数据进行解密处理 byte[] res = cipher.doFinal(data); String source = new String(res); System.out.println(source); } catch (Exception e) { throw new RuntimeException(e); } }
将加密和解密抽取出来形成方法:
private static String seed = "zhangSan"; private static final PublicKey publicKey; private static final PrivateKey privateKey; static { try { //获取一个RSA加密算法的密钥对生成器 KeyPairGenerator generator = null; generator = KeyPairGenerator.getInstance("RSA"); //初始化密钥对生成器的秘钥大小为512,使用的随机安全种子为seed generator.initialize(512,new SecureRandom(seed.getBytes())); //密钥对生成器生成密钥对 KeyPair keyPair = generator.genKeyPair(); //获取公钥,用来加密 publicKey = keyPair.getPublic(); //获取私钥,用来解密 privateKey = keyPair.getPrivate(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } }
加密:
/** * RSA加密 * @param source 待加密的字符串 * @return * @throws Exception */ public static String rsaEncode(String source) throws Exception { //获取一个RSA加密器 Cipher cipher = Cipher.getInstance("RSA"); //加密器初始化,当前模式为加密模式,使用的秘钥为公钥 cipher.init(Cipher.ENCRYPT_MODE,publicKey); //加密器对数据进行加密处理 byte[] result = cipher.doFinal(source.getBytes()); String s = Base64.getEncoder().encodeToString(result); return s; }
解密:
/** * RSA解密 * @param s 待解密的字符串 * @return * @throws Exception */ public static String rsaDecode(String s) throws Exception{ //获取一个RSA解密器 Cipher cipher = Cipher.getInstance("RSA"); //解密器初始化,当前模式为解密模式,使用的秘钥为私钥 cipher.init(Cipher.DECRYPT_MODE,privateKey); //需要将之前进行编码处理的数据进行还原 byte[] data = Base64.getDecoder().decode(s); //解密器对数据进行解密处理 byte[] res = cipher.doFinal(data); String source = new String(res); return source; }
测试:
public static void main(String[] args) { try { String s = rsaEncode("123123zs"); System.out.println(s); String source = rsaDecode(s); System.out.println(source); } catch (Exception e) { throw new RuntimeException(e); } }