栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java中的编码算法与常用的加密算法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java中的编码算法与常用的加密算法

URL编码算法

        URL编码的出现是出于兼容性的考虑,由于很多 服务器只识别ASCII字符,当包含中文这种非ASCII码时,如果字符是 A ~ Z , a ~ z , 0 ~ 9 以及 - 、 _ 、 . 、 * ,则保持不变; 如果是其他字符,先转换为 UTF-8 编码,然后对每个字节以 %XX 表示。

以下是基于URL编码算法的编码与解码,需要注意的是编码与解码时字符编码集应当设置为UTF-8

public class Demo01 {
	public static void main(String[] args) throws UnsupportedEncodingException {
		//编码
		String url = "https://www.baidu.com/s";
		String result = "语雀";
		String encode = URLEncoder.encode(result, "utf-8");
		System.out.println(encode);
		System.out.println(url+"?wd="+encode);
		
		//解码
		String param = "https://www.baidu.com/s?wd=%E6%88%91%E6%9C%AC%E5%B0%86%E5%BF%83%E5%90%91%E6%98%8E%E6%9C%88";
		String content = URLDecoder.decode(param, "utf-8");
		System.out.println(content);
	}
}
BASE64编码算法

Base64 编码可以把任意长度的二进制数据变为纯文本(在java中二进制数据为byte数组),并且纯文本内容中且只包含指定字符内 容: A ~ Z 、 a ~ z 、 0 ~ 9 、 + 、 / 、 = 。它的原理是把 3 字节的二进制数据按 6bit 一组,用 4 个int整数表示,然后查表, 把 int 整数用索引对应到字符,得到编码后的字符串。 6 位整数的范围总是 0 ~ 63 ,所以,能用 64 个字符表示:字符 A ~ Z 对应索引 0 ~ 25 ,字符 a ~ z 对应索引 26 ~ 51 ,字符 0 ~ 9 对应索引 52 ~ 61 ,最后两个索引 62 、 63 分别用字符 + 和 / 表示。

以下是基于BASE64编码算法的编码与解码

public class Demo02 {
	public static void main(String[] args) throws IOException {
		byte[] imagebyteArray = Files.readAllBytes
            (Paths.get("D:\tupian11\douban\珠峰队长.jpg"));
                    //读取本地图片并且保存在byte数组里
		String imageData= Base64.getEncoder().
            encodeToString(imagebyteArray);
                    //将图片以BASE64编码方式进行编码
		
		byte[] imageResultArray = Base64.getDecoder()
                .decode(imageData);
                    //将图片以BASE64编码方式进行解码
		Files.write(Paths.get("D:\tupian12\你的队长.jpg"),
                imageResultArray);
                    //将解码得到的保存在byte字节数组,并且写入指定目录
		
	}
}
小结

URL 编码和 Base64 编码都是编码算法,它们不是加密算法; URL 编码的目的是把任意文本数据编码为 % 前缀表示的文本,便于浏览器和服务器处理; Base64 编码的目的是把任意二进制数据编码为文本,但编码后数据量会增加 1/3 。

哈希算法(加密)

        什么是哈希算法呢?好像熟悉又陌生

        哈希算法( Hash )又称摘要算法( Digest ),它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。哈希算 法的目的:为了验证原始数据是否被篡改。

而哈希算法的特点在于: 相同的输入一定得到相同的输出; 不同的输入大概率得到不同的输出。

我们可以知道 :根据碰撞概率,哈希算法的输出长度越长,就越难产生碰撞,也就越安全。

常用的Hash算法
算法输出长度(位)输出长度(字节)
MD5128 bits16 bytes
SHA-1160 bits20 bytes
RipeMD-160160 bits20 bytes
SHA-256256 bits32 bytes
SHA-512512 bits64 bytes

MD5算法:

在使用 MessageDigest 时,我们首先根据哈希算法获取一个 MessageDigest 实例,然后,反复调用 update(byte[]) 输入数据。当输入结束后,调用 digest() 方法获得 byte[] 数组表示的摘要,最后,把它转换为十六进制的字符串。以下代码我们以MD5算法为例。

public class Demo06 {
	public static void main(String[] args) {
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			md5.update("天青色等烟雨".getBytes());
			md5.update("而我在等你".getBytes());
			byte[] resultArray=md5.digest();
			System.out.println(Arrays.toString(resultArray));
			md5.update("天青色等烟雨而我在等你".getBytes());
			byte[] resltArray2=md5.digest();
			System.out.println(Arrays.toString(resltArray2));
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
SHA-1算法:

SHA-1 也是一种哈希算法,它的输出是 160 bits ,即 20 字节。 SHA-1 是由美国国家安全局开发的, SHA 算法实际上是一个系列,包括 SHA-0 (已废弃)、 SHA-1 、 SHA-256 、 SHA-512 等。 在 Java 中使用 SHA-1 ,和 MD5 完全一样,只需要把算法名称改为" SHA-1 ":

public class main {
 public static void main(String[] args) {
 // 创建一个MessageDigest实例:
    MessageDigest md = MessageDigest.getInstance("SHA-1");
        // 反复调用update输入数据:
    md.update("天青色等烟雨".getBytes("UTF-8"));
    md.update("而我在等你".getBytes("UTF-8"));
        // 20 bytes: db8ac1c259eb89d4a131b253bacfca5f319d54f2
    byte[] results = md.digest();
    StringBuilder sb = new StringBuilder();
    for(byte bite : results) {
     sb.append(String.format("%02x", bite));
     }
    System.out.println(sb.toString());
     }
    }
Hmac加密算法

        Hmac 算法就是一种基于密钥的消息认证码算法,它的全称是 Hash-based Message Authentication Code ,是一种更安全的消息 摘要算法。

Hmac 算法总是和某种哈希算法配合起来用的。

例如,我们使用 MD5 算法,对应的就是 Hmac MD5 算法,它相当于“加盐” 的 MD5 : HmacMD5 ≈ md5(secure_random_key, input)

因此, HmacMD5 可以看作带有一个安全的 key 的 MD5 。使用 HmacMD5 而不是用 MD5 加 salt ,有如下好处:

HmacMD5 使用的 key 长度是 64 字节,更安全;

Hmac 是标准算法,同样适用于 SHA-1 等其他哈希算法;

Hmac 输出和原有的哈希算法长度一致。

可见, Hmac 本质上就是把 key 混入摘要的算法。

验证此哈希时,除了原始的输入数据,还要提供 key 。

为了保证安全,我们不会自 己指定 key ,而是通过 Java 标准库的 KeyGenerator 生成一个安全的随机的 key 。

public class Demo10 {
	public static void main(String[] args) {
		String str = "mlmdxbldm";
		try {
			KeyGenerator kg = KeyGenerator.getInstance("HmacMD5");
			SecretKey key = kg.generateKey();
			byte[] keyByteArray = key.getEncoded();
			StringBuilder sb = new StringBuilder();
			for(byte b : keyByteArray) {
				sb.append(String.format("%02X", b));
			}
			System.out.println(Arrays.toString(keyByteArray));
			System.out.println("密钥为"+sb);
			System.out.println("密钥长度为"+keyByteArray.length);
			System.out.println("密钥字节数为"+sb.length());
			//使用秘钥
			Mac mac = Mac.getInstance("HmacMD5");
			//初始化
			mac.init(key);
			//加密
			mac.update(str.getBytes());
			//
			byte[] result = mac.doFinal();
			StringBuilder sb1 = new StringBuilder();
			for(byte b : result) {
				sb1.append(String.format("%02X", b));
			}
			System.out.println("加密结果"+sb1);
			System.out.println("加密结果长度"+sb1.length());
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

和 MD5 相比,使用 HmacMD5 的步骤是:

1. 通过名称 HmacMD5 获取 KeyGenerator 实例;

2. 通过 KeyGenerator 创建一个 SecretKey 实例;

3. 通过名称 HmacMD5 获取 Mac 实例;

4. 用 SecretKey 初始化Mac实例;

5. 对 Mac 实例反复调用 update(byte[]) 输入数据;

6. 调用 Mac 实例的 doFinal() 获取最终的哈希值。

如果我们想恢复并且验证,其中new SecretKetSpec则是恢复密钥时传入数组的代码。

package com.my.hyz.homework;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class Demo11 {
	public static void main(String[] args) {
		String str = "mlmdxbldm";
		try {
			byte[] keyByteArray = {78, -100, -109, 29, 87, -46, -77, -36, 2, -2, -103,             -22, 45, -97, -70, 60, 102, 120, -21, 0, 79, 97, 111,
 23, 38, 39, -110, 7, 102, 6, -101, 105, -6, -87, 114, 
21, -82, 10, -119, -81, -57, 95, 95, -7, -97, -87, 79,
 -25, -87, -63, 65, -127, -90, -85, 75, 37, -36, -107,
 114, 64, 40, 111, -86, -24};
			SecretKey key = new SecretKeySpec(keyByteArray, "HmacMD5");
			Mac mac = Mac.getInstance("HmacMD5");
			//初始化
			mac.init(key);
			//加密
			mac.update(str.getBytes());
			//
			byte[] result = mac.doFinal();
			StringBuilder sb1 = new StringBuilder();
			for(byte b : result) {
				sb1.append(String.format("%02X", b));
			}
			System.out.println("加密结果"+sb1);
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1019902.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号