目录
目录
一.发展历史
1.1 古典密码学
凯撒密码,滚筒密码
1.2 近代密码学
Enigma机
1.3 现代密码学
二. 编码算法
不是加密和解密,只是为了方便传输数据或者本地存储而产生的。
2.1 Base64
由A-Z,a-z,+,/共64个字符组成,去掉i, I, o, O, +, /即为base58。
base64以三个字节为一组,如果最后一组不足3个字节,则使用“=”号补充。
(1)jdk实现
package com.john.javacrypto;
import org.junit.Test;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class JdkBase64Test {
@Test
public void jdkBase64Encode() {
String srcStr = "我的java加密课程";
String encodedStr = jdkBase64Encode(srcStr);
System.out.println("jdk base64 encoded str: " + encodedStr);
String decodedStr = jdkBase64Decode(encodedStr);
System.out.println("jdk base64 decoded str: " + decodedStr);
}
private String jdkBase64Encode(String srcStr){
return Base64.getEncoder().encodeToString(srcStr.getBytes(StandardCharsets.UTF_8));
}
private String jdkBase64Decode(String encodedString){
byte[] decodeBytes = Base64.getDecoder().decode(encodedString.getBytes(StandardCharsets.UTF_8));
return new String(decodeBytes, StandardCharsets.UTF_8);
}
}
(2)commons-codec实现
package com.john.javacrypto;
import org.apache.commons.codec.binary.Base64;
import org.junit.Test;
import java.nio.charset.StandardCharsets;
public class CommonsCodecBase64Test {
@Test
public void commonsCodecBase64Encode() {
String srcStr = "我的java加密课程";
String encodedStr = commonsCodecBase64Encode(srcStr);
System.out.println("commonsCodec base64 encoded str: " + encodedStr);
String decodedStr = commonsCodecBase64Decode(encodedStr);
System.out.println("commonsCodec base64 decoded str: " + decodedStr);
}
private String commonsCodecBase64Encode(String srcStr){
return Base64.encodeBase64String(srcStr.getBytes(StandardCharsets.UTF_8));
}
private String commonsCodecBase64Decode(String encodedString){
byte[] decodeBytes = Base64.decodeBase64(encodedString.getBytes(StandardCharsets.UTF_8));
return new String(decodeBytes, StandardCharsets.UTF_8);
}
}
2.2 URL编码
表单提交时:application/x-www-form-urlencoded
(1)jdk实现
package com.john.javacrypto.urlencode;
import org.junit.Test;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class JdkUrlEncodedTest {
@Test
public void testUrlEncode() throws UnsupportedEncodingException {
String srcUrl = "我的java加密课程";
String encodedUrl = urlEncode(srcUrl);
//encodedUrl: %E6%88%91%E7%9A%84java%E5%8A%A0%E5%AF%86%E8%AF%BE%E7%A8%8B
System.out.println("encodedUrl: " + encodedUrl);
String decodedUrl = urlDecode(encodedUrl);
//decodedUrl: 我的java加密课程
System.out.println("decodedUrl: " + decodedUrl);
}
private String urlEncode(String srcUrl) throws UnsupportedEncodingException {
return URLEncoder.encode(srcUrl, StandardCharsets.UTF_8.name());
}
private String urlDecode(String encodedUrl) throws UnsupportedEncodingException {
return URLDecoder.decode(encodedUrl, StandardCharsets.UTF_8.name());
}
}
(2)commons-codec实现
package com.john.javacrypto.urlencode;
import org.apache.commons.codec.net.URLCodec;
import org.junit.Test;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
public class CommonsCodecUrlCodeTest {
@Test
public void testUrlEncode() throws Exception {
String srcUrl = "我的java加密课程";
String encodedUrl = urlEncode(srcUrl);
//encodedUrl: %E6%88%91%E7%9A%84java%E5%8A%A0%E5%AF%86%E8%AF%BE%E7%A8%8B
System.out.println("encodedUrl: " + encodedUrl);
String decodedUrl = urlDecode(encodedUrl);
//decodedUrl: 我的java加密课程
System.out.println("decodedUrl: " + decodedUrl);
}
private String urlEncode(String srcUrl) throws UnsupportedEncodingException {
URLCodec urlCodec = new URLCodec();
return urlCodec.encode(srcUrl, StandardCharsets.UTF_8.name());
}
private String urlDecode(String encodedUrl) throws Exception {
URLCodec urlCodec = new URLCodec();
return urlCodec.decode(encodedUrl, StandardCharsets.UTF_8.name());
}
}
三. 摘要算法
3.1 定义
摘要算法也叫hash算法,散列算法,数字摘要,消息摘要。它是一种单向算法,用户可以通过hash算法对目标信息生成一段特定长度的唯一hash值,但不能通过这个hash值重新获取目标信息。
3.2 应用场景
密码、信息完整性校验、数字签名。
3.3 常见算法
- MD5:Message-Digest Algorithm,结果占128位(16字节,32个字符);
- SHA:Secure Hash Algorithm,安全散列算法
- SHA-256(32字节,64个字符)
- SHA-0, SHA-1, SHA-512
- MAC:Message Authentication Code,消息认证码,是一种带有密钥的hash函数
- 其他:MD2, MD4, HAVAL
3.4 代码实现
3.4.1 MD5
(1)JDK实现
package com.john.javacrypto.messagedigest;
import org.junit.Test;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
public class JdkMD5 {
@Test
public void test() throws Exception {
String srcString = "你好,Hellow World!";
byte[] srcBytes = srcString.getBytes(StandardCharsets.UTF_8);
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] digestBytes = md5.digest(srcBytes);
/**
* 当srcBytes较大时:可以将srcBytes进行切分,然后循环update
* md5.update(srcBytes);
* md5.digest();
*/
//md5 hex string: 4ff1dfc5c3f2f3ebc03a7747b6453597
System.out.println("md5 hex string: " + converBytes2HexStr(digestBytes));
}
private String converBytes2HexStr(byte[] bytes) {
StringBuilder res = new StringBuilder();
for (byte b : bytes) {
//获取b的补码的后8位
String hex = Integer.toHexString((int) b & 0xFF);
if (hex.length() == 1) {
res.append("0");
}
res.append(hex);
}
return res.toString();
}
}
(2)commons-codec实现
package com.john.javacrypto.messagedigest;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.Test;
public class CodecMD5 {
@Test
public void test() {
String srcString = "你好,Hellow World!";
//md5 hex string: 4ff1dfc5c3f2f3ebc03a7747b6453597
System.out.println("md5 hex string: " + DigestUtils.md5Hex(srcString));
}
}
3.4.2 SHA256
(1)JDK实现
package com.john.javacrypto.sha;
import com.john.javacrypto.utils.MessageDigestUtils;
import org.junit.Test;
public class SHA256Test {
@Test
public void test() throws Exception {
String srcString = "你好,Hellow World!";
//SHA-256 hex string: 422b4d37714568aade2818bf6ae0ea41bb9d89f36b13cc101986c4440b15019d
System.out.println("SHA-256 hex string: " + MessageDigestUtils.doDigestAlgorithm(srcString, "SHA-256"));
}
}
(2)codec实现
package com.john.javacrypto.sha;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.Test;
public class CodecSHA256 {
@Test
public void test() {
String srcString = "你好,Hellow World!"