文章目录
1. base64加密
从现在加密算法的复杂性来看Base64这种都不好意思说自己是加密,不过对于完全不懂计算机的人来说也够用了。采用Base64编码具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
Base64编码一般用于url的处理,或者说任何你不想让普通人一眼就知道是啥的东西都可以用Base64编码处理后再发布在网络上。
1.1 jdk原生实现
/**
* 使用jdk原生实现base64
*/
@Test
public void test1() throws UnsupportedEncodingException {
String str = "陈彦杰";
//编码 1.8才提供
Base64.Encoder encoder = Base64.getEncoder();
String encoderStr = encoder.encodeToString(str.getBytes("utf-8"));
System.out.println("encoderStr:" + encoderStr);//6ZmI5b2m5p2w
//解码
Base64.Decoder decoder = Base64.getDecoder();
byte[] decode = decoder.decode(encoderStr.getBytes());
String decoderStr = new String(decode, "utf-8");
System.out.println("decoderStr:" + decoderStr);
}
1.2 commons-codec实现
/**
* 使用commons-codec实现base64
*/
@Test
public void test2() throws UnsupportedEncodingException {
String str = "陈彦杰";
//编码
String encoderStr = org.apache.commons.codec.binary.Base64.encodeBase64String(str.getBytes(UTF8));
System.out.println("encoderStr:" + encoderStr);//6ZmI5b2m5p2w
//解码
byte[] bytes = org.apache.commons.codec.binary.Base64.decodeBase64(encoderStr.getBytes());
String decoderStr = new String(bytes, UTF8);
System.out.println("decoderStr:" + decoderStr);
}
2. url加密
2.1 jdk原生实现
/**
* 使用jdk原生实现URL编码
*/
@Test
public void test1() throws UnsupportedEncodingException {
String str = "陈彦杰java";
//编码
String encode = URLEncoder.encode(str, UTF8);
System.out.println("encode:" + encode);//%E9%99%88%E5%BD%A6%E6%9D%B0java
//解码
String decode = URLDecoder.decode(encode, UTF8);
System.out.println("decode:" + decode);
}
3. Hash加密/散列加密(摘要加密)
引文:
如果开发者需要保存密码(比如网站用户的密码),要考虑如何保护这些密码数据,网站用户密码的泄露是一件非常严重的事情,容易引起用户恐慌,
所以在安全方面是重中之重,直接将密码以明文写入数据库中是极不安全的,因为任何可以打开数据库的人,都将可以直接看到这些密码。
解决的办法是将密码加密后再存储进数据库,比较常用的加密方法是使用哈希函数(Hash Function),也就是摘要加密。
通过哈希函数,我们就可以将密码的哈希值存储进数据库。用户登录网站的时候,我们可以检验用户输入密码的哈希值是否与数据库中的哈希值相同。
由于哈希函数是不可逆的
,即使有人打开了数据库,也无法看到用户的密码是多少。(但不意味着存储经过哈希函数加密后的密码就是绝对的安全!)
介绍:摘要加密是一种不需要密钥的加密算法,生成的密文是唯一的、定长的并且无法破解,具有不可逆性、唯一性。常见的算法有
MD5、SHA
等
原理:通过hash算法(单向算法)对目标信息生成一段特定长度的唯一hash值。
应用场景:密码加密,数字签名,文件完整性的校验 ,版权等应用场景。
输出长度 | 安全性 | 计算速度 | 常见应用 | |
---|---|---|---|---|
MD5 | 128位(16字节) | 不安全,易受碰撞攻击 | 快 | 文件校验、散列密码 |
SHA-1 | 160位(20字节) | 不再安全,易受碰撞攻击 | 中等 | 数字签名、SSL证书 |
SHA-256 | 256位(32字节) | 相对较安全,较难受碰撞攻击 | 相对较慢 | 安全存储密码、数字签名 |
SHA-512 | 512位(64字节) | 高安全性,抗碰撞能力强 | 更慢 | 密码学、数字签名、数据完整性校验 |
3.1 md5加密
- MessageDigestUtils
public class MessageDigestUtils {
private static final String UTF8 = StandardCharsets.UTF_8.name();
/**
*
* @param str
* @param algorithm
* @return
* @throws NoSuchAlgorithmException
* @throws UnsupportedEncodingException
*/
public static String doGetDigest(String str, String algorithm) throws NoSuchAlgorithmException, UnsupportedEncodingException {
//获取消息摘要算法对象
MessageDigest md = MessageDigest.getInstance(algorithm);
//获取原始内容的字节数组
byte[] originalBytes = str.getBytes(UTF8);
//获取到摘要结果
byte[] digest = md.digest(originalBytes);//QX�L�����-d�[�[
//当originalBytes比较大的时候,循环的进行update()
// md.update(originalBytes);
// byte[] digest = md.digest();//QX�L�����-d�[�[
// System.out.println(new String(digest,UTF8));
// System.out.println(Arrays.toString(digest));//[81, 88, -6, 76, -107, -111, -115, -24, -73, -64, 45, 100, -84, 91, -7, 91]
return HexUtils.convertBytes2HexStr( digest);
}
/**
* 获取mac的消息摘要
* @param str 原始内容
* @param key mac算法的key
* @param algorithm 算法名字,如HmacMd5,HmacSha-256
* @return
* @throws NoSuchAlgorithmException
* @throws UnsupportedEncodingException
*/
public static String doGetDigestMac(String str,String key, String algorithm) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
//获取消息摘要算法对象
Mac mac = Mac.getInstance(algorithm);
//获取key对象并初始化mac
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(UTF8), algorithm);
mac.init(secretKeySpec);
//获取原始内容的字节数组
byte[] originalBytes = str.getBytes(UTF8);
//获取到摘要结果
byte[] digest = mac.doFinal(originalBytes);//QX�L�����-d�[�[
//当originalBytes比较大的时候,循环的进行update()
// md.update(originalBytes);
// byte[] digest = md.digest();//QX�L�����-d�[�[
// System.out.println(new String(digest,UTF8));
// System.out.println(Arrays.toString(digest));//[81, 88, -6, 76, -107, -111, -115, -24, -73, -64, 45, 100, -84, 91, -7, 91]
return HexUtils.convertBytes2HexStr( digest);
}
}
- HexUtils
public class HexUtils {
/**
* 把字节数组转为16进制字符串,如果一个字节转为16进制字符后不足两位,则前面补0
*
* @param digest
* @return
*/
public static String convertBytes2HexStr(byte[] digest) {
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
// System.out.println(b);
//获取b的补码的后8位
// System.out.print((int) b+" ");
// String hexString = Integer.toHexString(((int) b) );
//15-->15&0xff=f
//16-->16&0xff=10
String hexString = Integer.toHexString(((int) b) & 0xff);
// System.out.print(hexString);
// System.out.println();
if (hexString.length() == 1) {
hexString = "0" + hexString;
}
sb.append(hexString);
}
return sb.toString();
}
/**
* 把16进制字符串(一定是偶数位的,因为convertBytes2HexStr已经处理过)转为字节数组
*
* @param hexStr
* @return
*/
public static byte[] convertHex2Bytes(String hexStr) {
//一个字节可以转化为2个16进制字符
int length = hexStr.length() / 2;
byte[] result = new byte[length];
for (int i = 0; i < length; i++) {
//hexStr:abcd
//Integer.parseInt:把s转为10进制数,radix指定s是什么进制的数
//获取每个字节的高4位,hexStr.substring(2,3)->c
int high4 = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
//获取每个字节的低4位,hexStr,substring(3,4)=>d
int low4 = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high4 * 16 + low4);
}
return result;
}
}
3.1.1 jdk原生实现
/**
* 使用jdk原生实现Md5
*/
@Test
public void test3() throws UnsupportedEncodingException, NoSuchAlgorithmException {
String str = "陈彦杰";
String algorithm = "MD5";
//结果32位
String hexStr = MessageDigestUtils.doGetDigest(str, algorithm);//5158fa4c95918de8b7c02d64ac5bf95b
System.out.println(hexStr);
}
3.1.2 commons-codec实现
/**
* 使用codec来实现md5
*/
@Test
public void test4() throws UnsupportedEncodingException, NoSuchAlgorithmException {
String str = "陈彦杰";
//结果32位
String hexStr= DigestUtils.md5Hex(str.getBytes("utf-8"));//5158fa4c95918de8b7c02d64ac5bf95b
System.out.println(hexStr);
}
3.2 SHA-1/SHA-256/SHA-512加密
3.2.1 jdk原生实现
/**
* 使用jdk原生实现Sha256
*/
@Test
public void test3() throws UnsupportedEncodingException, NoSuchAlgorithmException {
String str = "陈彦杰";
String algorithm = "SHA-1";
//结果64位
String hexStr = MessageDigestUtils.doGetDigest(str, algorithm);//38f9d59c4d89375e5c557616a1ea29a8db09776a44cfe703344a12f762aa3236
System.out.println(hexStr);
}
3.2.2 commons-codec实现
/**
* 使用codec来实现Sha256
*/
@Test
public void test4() throws UnsupportedEncodingException, NoSuchAlgorithmException {
String str = "陈彦杰";
//结果64位
String hexStr= DigestUtils.sha1Hex(str.getBytes("utf-8"));//38f9d59c4d89375e5c557616a1ea29a8db09776a44cfe703344a12f762aa3236
System.out.println(hexStr);
}
3.3 mac加密
mac摘要和digest算法(md5,sha)不同的地方就是加盐
3.3.1 jdk原生实现
/**
* 使用jdk原生实现Mac
*/
@Test
public void test3() throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
String str = "陈彦杰";
String algorithm = "HmacMd5";
//指定密钥,mac摘要和digest算法那(md5,sha)不同的地方就是加盐
String key = "123";
String hexStr = MessageDigestUtils.doGetDigestMac(str, key, algorithm);//71302a2865ad442bd45d3f1bebf76de3
System.out.println(hexStr);
algorithm = "HmacSHA256";
//指定密钥,mac摘要和digest算法那(md5,sha)不同的地方就是加盐
hexStr = MessageDigestUtils.doGetDigestMac(str, key, algorithm);//9b2d5ac948bf14a61f758c181cf4360987ae603654d9308c5a8a3b5746be287c
System.out.println(hexStr);
algorithm = "HmacSHA512";
//指定密钥,mac摘要和digest算法那(md5,sha)不同的地方就是加盐
hexStr = MessageDigestUtils.doGetDigestMac(str, key, algorithm);//e34c61875231f13aa7bf5ef74d6d1dd87c8d105395c0ceb32ca58a7141701ea0ddb2c1d0ccf64bdcf1fddfacf508225dd3463ed341e09c3b0ae47285890e8f84
System.out.println(hexStr);
}
3.3.2 commons-codec实现
/**
* 使用codec来实现Mac
*/
@Test
public void test4() throws UnsupportedEncodingException, NoSuchAlgorithmException {
String str = "陈彦杰";
//指定密钥,mac摘要和digest算法那(md5,sha)不同的地方就是加盐
String key = "123";
String hmacMd5Hex = new HmacUtils(HmacAlgorithms.HMAC_MD5, key.getBytes("utf-8")).hmacHex(str.getBytes("utf-8"));
System.out.println(hmacMd5Hex);//71302a2865ad442bd45d3f1bebf76de3
String hmacSHA256Hex = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key.getBytes("utf-8")).hmacHex(str.getBytes("utf-8"));
System.out.println(hmacSHA256Hex);//9b2d5ac948bf14a61f758c181cf4360987ae603654d9308c5a8a3b5746be287c
String hmacSHA512Hex = new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key.getBytes("utf-8")).hmacHex(str.getBytes("utf-8"));
System.out.println(hmacSHA512Hex);//e34c61875231f13aa7bf5ef74d6d1dd87c8d105395c0ceb32ca58a7141701ea0ddb2c1d0ccf64bdcf1fddfacf508225dd3463ed341e09c3b0ae47285890e8f84
}
4. 对称加密
采用
单钥密码
系统的加密方法,同一个密钥
可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。