加密算法

  • 编码方式
  • 不可逆算法
  • 对称加密
  • 非对称加密

编码方式(Base64)

原理:ASCII 编码 ascall表
Base64编码表

码值	字符	码值	字符	码值	字符	码值	字符
0	A	16	Q	32	g	48	w
1	B	17	R	33	h	49	x
2	C	18	S	34	i	50	y
3	D	19	T	35	j	51	z
4	E	20	U	36	k	52	0
5	F	21	V	37	i	53	1
6	G	22	W	38	m	54	2
7	H	23	X	39	n	55	3
8	I	24	Y	40	o	56	4
9	J	25	Z	41	p	57	5
10	K	26	a	42	q	58	6
11	L	27	b	43	r	59	7
12	M	28	c	44	s	60	8
13	N	29	d	45	t	61	9
14	O	30	e	46	u	62	+
15	P	31	f	47	v	63	/
  1. 将要编码的数据以三个字符24bit为一组
  2. 对24bit进行重组,以6bit为一组分成4组
  3. 每组开头添加2个0,构成每组8个bit。此时一共32个bit
  4. 根据base64编码表进行重新编码

使用:java8中内置了Base64的编码器和解码器

https://www.runoob.com/java/java8-base64.html

在这里插入图片描述

import java.util.Base64;
import java.util.UUID;
import java.io.UnsupportedEncodingException;
 
public class Java8Tester {
   public static void main(String args[]){
      try {
        
         // 使用基本编码
         String base64encodedString = Base64.getEncoder().encodeToString("runoob?java8".getBytes("utf-8"));
         System.out.println("Base64 编码字符串 (基本) :" + base64encodedString);
        
         // 解码
         byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString);
        
         System.out.println("原始字符串: " + new String(base64decodedBytes, "utf-8"));
         base64encodedString = Base64.getUrlEncoder().encodeToString("runoob?java8".getBytes("utf-8"));
         System.out.println("Base64 编码字符串 (URL) :" + base64encodedString);
        
         StringBuilder stringBuilder = new StringBuilder();
        
         for (int i = 0; i < 10; ++i) {
            stringBuilder.append(UUID.randomUUID().toString());
         }
        
         byte[] mimeBytes = stringBuilder.toString().getBytes("utf-8");
         String mimeEncodedString = Base64.getMimeEncoder().encodeToString(mimeBytes);
         System.out.println("Base64 编码字符串 (MIME) :" + mimeEncodedString);
         
      }catch(UnsupportedEncodingException e){
         System.out.println("Error :" + e.getMessage());
      }
   }
}

不可逆算法

说明:不可逆算法在加密过程中不加入密钥,明文加密,加密后无法解密,只能通过相同明文加密来校验是否是同一数据

常用算法: 哈希算法md5(校验文件完整性),BCrypt/SHA加密算法

md5

原理简单解释
底层原理:

  1. 处理原文
  2. 设置初始值
  3. 循环加工
  4. 拼接结果

使用

@Component
public class Md5Util {

    /**
     * byte[]字节数组 转换成 十六进制字符串
     * @param arr 要转换的byte[]字节数组
     * @return String 返回十六进制字符串
     */




    private static String hex(byte[] arr) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < arr.length; ++i) {
            sb.append(Integer.toHexString((arr[i] & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString();
    }


    /**
     * MD5加密,并把结果由字节数组转换成十六进制字符串
     * @param str 要加密的内容
     * @return String 返回加密后的十六进制字符串
     */
    private static String md5Hex(String str) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(str.getBytes());
            return hex(digest);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.toString());
            return "";
        }
    }



    /**
     * 生成含有随机盐的密码
     * @param password 要加密的密码
     * @return String 含有随机盐的密码
     */
    public static String getSaltMD5(String password) {
// 生成一个16位的随机数
//        Random random = new Random();
//        StringBuilder sBuilder = new StringBuilder(16);
//        sBuilder.append(random.nextInt(99999999)).append(random.nextInt(99999999));
//        int len = sBuilder.length();
//        if (len < 16) {
//            for (int i = 0; i < 16 - len; i++) {
//                sBuilder.append("0");
//            }
//        }
//        // 生成最终的加密盐
//        String salt1 = sBuilder.toString();
        //也可以使用固定的盐值如“1234567890123456”,16位字符串
        String salt2 = "dkaaieybdg1548lk";

        password = md5Hex(password + salt2);
        char[] cs = new char[48];
        for (int i = 0; i < 48; i += 3) {
            cs[i] = password.charAt(i / 3 * 2);
            char c = salt2.charAt(i / 3);
            cs[i + 1] = c;
            cs[i + 2] = password.charAt(i / 3 * 2 + 1);
        }
        return String.valueOf(cs);
    }



    /**
     * 验证加盐后是否和原密码一致
     * @param password 原密码
     * @param password 加密之后的密码
     *@return boolean true表示和原密码一致 false表示和原密码不一致
     */
    public static boolean getSaltverifyMD5(String password, String md5str) {
        char[] cs1 = new char[32];
        char[] cs2 = new char[16];
        for (int i = 0; i < 48; i += 3) {
            cs1[i / 3 * 2] = md5str.charAt(i);
            cs1[i / 3 * 2 + 1] = md5str.charAt(i + 2);
            cs2[i / 3] = md5str.charAt(i + 1);
        }
        String Salt = new String(cs2);
        return md5Hex(password + Salt).equals(String.valueOf(cs1));
    }



    public static void main(String[] args) {
// 原密码
        String plaintext = "235463wee";

// 获取加盐后的MD5值
        String ciphertext = Md5Util.getSaltMD5(plaintext);
        System.out.println("加盐后MD5:" + ciphertext);
        System.out.println("是否是同一字符串:" + Md5Util.getSaltverifyMD5(plaintext, ciphertext));
    }
}

BCrypt
使用:
maven依赖

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
</dependency>

测试

String gensalt = BCrypt.gensalt();//这个是盐  29个字符,随机生成
System.out.println(gensalt);
String password = BCrypt.hashpw("123456", gensalt);  //根据盐对密码进行加密
System.out.println(password);//加密后的字符串前29位就是盐
//校验,该加密不支持解密
boolean checkpw = BCrypt.checkpw("123456",  "$2a$10$61ogZY7EXsMDWeVGQpDq3OBF1.phaUu7.xrwLyWFTOu8woE08zMIW");
System.out.println(checkpw);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值