加密算法集合
0.加密算法概述
散列算法
散列算法,又称哈希函数,是一种单向加密算法。散列(Hash)函数对不同长度的输入消息,产生固定长度的输出。这个固定长度的输出称为原输入消息的”散列”或”消息摘要”(Message digest)。散列算法不算加密算法,因为其结果是不可逆的,不是用来加密的,而是用来签名。常见的有MD5、SHA1、HMAC等。
- MD5是一种不可逆的加密算法,目前是最牢靠的加密算法之一,它对应任何字符串都可以加密成一段唯一的长度为128bits的串,通常用16进制的32个字符来表示该加密结果。
- SHA1对长度小于264的输入,输出长度为160bit的散列值。而SHA-1基于MD5,MD5又基于MD4。
- HMAC利用MD5、SHA1等哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。也就是说HMAC是需要一个密钥的。所以,HMAC_SHA1也是需要一个密钥的,而SHA1不需要。
对称加密算法
对称式加密就是加密和解密使用同一个密钥。信息接收双方都需事先知道密匙和加解密算法且其密匙是相同的,之后便是对数据进行加解密了。常见的有DES、3DES、AES等。
DES是一种数据加密标准,速度较快,适用于加密大量数据的场合。
3DES是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。
AES是一个使用128位分组块的分组加密算法,分组块和128、192或256位的密钥一起作为输入,在4×4的字节数组上进行操作。
非对称加密算法
非对称式加密就是加密和解密所使用的不是同一个密钥,通常有两个密钥,称为”公钥”和”私钥”,它们两个必需配对使用,否则不能打开加密文件。如果使用公钥对数据进行加密,只有对应的私钥才能进行解密;如果使用私钥对数据进行加密,只有对应的公钥才能进行解密。常见的有RSA、DSA、ECC等。
- RSA是一个支持可变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的。
- DSA数字签名算法,是一种标准的 DSS(数字签名标准),严格来说不算加密算法。
- ECC是椭圆曲线密码编码学。
Base64加密算法
通常用于把二进制数据编码为可写的字符形式的数据,对数据内容进行编码来适合传输(可以对img图像编码用于传输)。这是一种可逆的编码方式。编码后的数据是一个字符串,其中包含的字符为:A-Z、a-z、0-9、+、/,共64个字符(26 + 26 + 10 + 1 + 1 = 64,其实是65个字符,“=”是填充字符。Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。原文的字节最后不够3个的地方用0来补足,转换时Base64编码用=号来代替。这就是为什么有些Base64编码会以一个或两个等号结束的原因,中间是不可能出现等号的,但等号最多只有两个。其实不用”=”也不耽误解码,之所以用”=”,可能是考虑到多段编码后的Base64字符串拼起来也不会引起混淆。)
1.十六进制字符串与字节数组转换
十六进制字符串与字节数组转换在加密工具中被广泛运用,后续的加密工具包基本都要用到。本质就是每个字节转换成一个两位字符串合并起来,反过来就是字符串拆成一个个两位字符串,分别转换成字节。
工具类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42public class StringHexUtils {
/**
* 从字节数组到十六进制字符串转换
*
* @param src
* @return 十六进制字符串
*/
public static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
//byte数组转换成16进制字符串会补足两位自动在前面加0
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
/**
* 从十六进制字符串到字节数组转换
*
* @param src
* @return
*/
public static byte[] HexStringToBytes(String src) {
src = src.length() % 2 != 0 ? "0" + src : src;
byte[] b = new byte[src.length() / 2];
for (int i = 0; i < b.length; i++) {
int index = i * 2;
int v = Integer.parseInt(src.substring(index, index + 2), 16);
b[i] = (byte) v;
}
return b;
}
}测试结果:
1
2
3
4
5
6
7
8
9
10
11
12
13public class UtilsTest {
public static void main(String[] args) {
byte[] test = new byte[]{1,3,4,117,56,9};
String ans = StringHexUtils.bytesToHexString(test);
System.out.println(ans);
System.out.println(Arrays.toString(StringHexUtils.HexStringToBytes(ans)));
}
}
//通过以上测试方法,在控制台得到测试结果:
//010304753809
//[1, 3, 4, 117, 56, 9]byte数组转换成16进制字符串会补足两位,不满两位时自动在前面加0补足;
该工具类主要运用了Integer.toHexString(int),Integer.parseInt(“string”, 16)这两个方法来实现。
2.Des3加密
工具类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
public class Des3Utils {
//算法名称
private static final String KEY_ALGORITHM = "desede";
// 算法名称/加密模式/填充方式
private static final String CIPHER_ALGORITHM = "DESede/CBC/NoPadding";
/**
* CBC加密
* @param key 密钥
* @param keyiv IV向量
* @param data 明文
* @return Base64编码的密文
* @throws Exception
key = "111111112222222233333333",本质上就是三个密钥拼接而成,就是"11111111"、"22222222"、"33333333"。
keyiv = {0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38};
*/
public static byte[] des3EncodeCBC(String key, byte[] keyiv, String data) throws Exception {
Key deskey = keyGenerator(key);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
IvParameterSpec ips = new IvParameterSpec(keyiv);
cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
byte[] bb = data.getBytes();
byte[] aa = null;
if(bb.length%8>0){
aa = new byte[(bb.length/8+1)*8];
System.arraycopy(bb, 0, aa, 0, bb.length);
}else{
aa = bb;
}
byte[] bOut = cipher.doFinal(aa);
return bOut;
}
/**
*
* 生成密钥key对象
* @param keyStr 密钥字符串
* @return 密钥对象
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws Exception
*/
private static Key keyGenerator(String keyStr) throws Exception {
DESedeKeySpec KeySpec = new DESedeKeySpec(keyStr.getBytes());
SecretKeyFactory KeyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
return ((Key) (KeyFactory.generateSecret(((java.security.spec.KeySpec) (KeySpec)))));
}
/**
* CBC解密
* @param key 密钥
* @param keyiv IV
* @param data Base64编码的密文
* @return 明文
* @throws Exception
*/
public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data) throws Exception {
Key deskey = keyGenerator(new String(key));
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
IvParameterSpec ips = new IvParameterSpec(keyiv);
cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
byte[] bOut = cipher.doFinal(data);
return bOut;
}
/**
* CBC解密
*
* @param key 密钥
* @param keyiv IV
* @param data Base64编码的密文
* @return 明文
* @throws Exception
*/
public static byte[] des3DecodeCBC(String key, byte[] keyiv, byte[] data) throws Exception {
Key deskey = keyGenerator(key);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
IvParameterSpec ips = new IvParameterSpec(keyiv);
cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
byte[] bOut = cipher.doFinal(data);
return bOut;
}
/**
* CBC解密
*
* @param key 密钥
* @param keyiv IV
* @param data Base64编码的密文
* @return 明文
* @throws Exception
*/
public static byte[] des3DecodeCBC(String key, byte[] keyiv, String data) throws Exception {
byte[] dataByte = StringHexUtils.HexStringToBytes(data);
Key deskey = keyGenerator(key);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
IvParameterSpec ips = new IvParameterSpec(keyiv);
cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
byte[] bOut = cipher.doFinal(dataByte);
return bOut;
}
/**
* 自己加的一个封装Des3加密的方法,输入三个字符串,我们先将其组成一个数据字符串,然后进行加密。
*
* @param in_acct
* @param tran_seq
* @param orderTime
* @return
* @throws Exception
*/
public static String des3(String in_acct,String tran_seq,String orderTime) throws Exception {
StringBuilder sb = new StringBuilder();
sb.append("in_acct").append("=").append(in_acct).append("&").append("tran_seq").append("=").append(tran_seq).append("&").append("orderTime").append("=").append(orderTime);
byte[] aa = des3EncodeCBC("111111112222222233333333",new byte[]{0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38},sb.toString());
//对字符串Des3加密得到的是字节数组,需要转换成字符串输出
String bb = StringHexUtils.bytesToHexString(aa);
//将小写字符全都大写
return bb.toUpperCase();
}
}String.toUpperCase()方法可以将字符串中小写字符全都大写,String.toLowerCase()方法可以将字符串中大写字符全都小写。
3.SHA256加密
工具类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class SHA256Utils {
public static String SHA256Str(String str) {
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance("SHA-256");
//str.getBytes("UTF-8")是将str字符串的每个字符转换成一个字节
messageDigest.update(str.getBytes("UTF-8"));
//再将字节数组转换成十六进制字符串
String encodeStr = StringHexUtils.bytesToHexString(messageDigest.digest());
return encodeStr;
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}注意str.getBytes(“UTF-8”)与StringHexUtils.HexStringToBytes(str)的区别:前者将每个字符按utf-8字符集转换成一个字节;后者将每两个字符转换成一个字节。
4.HMACSHA256加密
工具类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.TreeMap;
public class HMACSHA256Utils {
/**
* 字符串通过HMACSHA256加密为字符串
* @param key
* @param data
* @return
*/
public static String hMacSha256str(String key,String data) {
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
sha256_HMAC.init(secret_key);
return bytesToHexString(sha256_HMAC.doFinal(data.getBytes("UTF-8")));
} catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
/**
* 从字节数组到十六进制字符串转换
*
* @param src
* @return 十六进制字符串
*/
public static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
//byte数组转换成16进制字符串会补足两位自动在前面加0
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
/**
* 自己加的一个封装HMACSHA256加密的方法,输入一个Map,将Map中的键值对按字典序进行拼接然后加密
*
* @return
*/
public static String getSign(String key, Map<String,String> data) {
//将数据转移到TreeMap中
TreeMap<String, String> map = new TreeMap();
for (String name : data.keySet()) {
map.put(name, data.get(name));
}
StringBuilder sb = new StringBuilder();
for (String name : map.keySet()) {
sb.append(name).append("=").append(map.get(name)).append("&");
}
return hMacSha256str(key, sb.substring(0,sb.length() - 1));
}
}直接foreach遍历TreeMap,就是将map中的entry按key的字典序排序后,按从小到大的顺序遍历。
5.SHA256WithRSA加密
该加密计算公式可描述为:base64encode(rsa(sha256(原字符串))),是由三种加密算法组合而成的加密算法,工具类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114public class SHA256withRSA {
private static final String KEY_PRIVATE = "-----BEGIN PRIVATE KEY-----\n" +
"MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDJ1Z3Mjp8GMdu/\n" +
"YmkEq9ccuDNlRHyI0429UBKCVU25oR2kQuC/reQKVZ0Xpo69zMs5+gGz7/siCtij\n" +
"PIyUr5Jp/srDm6i1uKJSkuP2QsdIau3NhMIUXpb2CcLBtXxfr6D/rrphVh/ePEGt\n" +
"3kEnkHONHSvpHEVlKSaxcG2cubRHfzysD75Xh1EbMc8yYRS+iOCuJVtCNyQeAHZn\n" +
"rkwPApxksti108XNo9/jU5vskm8kjEkv9ufnI31C8DgEUjIsxuhnSygVfa6k9hc7\n" +
"6Zbh1/znDirrIfRAbWCdgicpmj0BAgPv/3OWwlKb+es1IirNThH1nBjZ0ug3c5O3\n" +
"QNU5ntqPAgMBAAECggEAZ1O78DAHi3VU6XqpBuIuQx6t+ScBlk6vnn5yq1SecOzh\n" +
"rukqBBcyynOf866qHtLMK8covgSajYf99juWQLxNeYQeK9vxl+6I8zsOB1GSkilj\n" +
"yrYvYZw3Log6s06E+LuB8cNy2UftEqnIeglxU57o+RI5G6MEh9B0ZZyIERclCwBY\n" +
"mIFDj0OAnusznnfX+AeOytmfjDGtBo+gEAMKyCnCxKox7EGklgGmKZvMQ1Tuhtw7\n" +
"0jIjNAznAb4kN9nlwEaCg/c53DuPEj5zXsnlYZs59swo9rJy1+WT79BIW6YPLVP5\n" +
"K5w3L4CWLuu5zhTbGFUnLGj+IyXf+Irn2BAB93mqsQKBgQDsAh+PkLJg9/TOfyN7\n" +
"rNCzX7oJvi+TiJhCr+Yzwb2Ao029nfpYN4o+3S+F/hPXU82odDAIKsiMM40LGXhr\n" +
"v2niuGRW17MVpdXtxgLRX34Bbm50+5PwO+Gfjze0VoGsCqLJZwEJXAGRvnSH61DM\n" +
"envmvNIvQwP4aGsFuDZKvN54hwKBgQDa7m2ADpH5/ChriGLSfLx7VFJhRgCNDI4M\n" +
"8bGgKcUucjWSr2FabAh9hsVP72qQnTZXEYpTUufJXuKTqGIjEkuUyohPs0zvGNPk\n" +
"x467t0EmPPZr/DXGttwhtEqN1f/3yJ7Mqe4qC++Y8LwJiTwc/hYDMoAMVfmDIQNR\n" +
"QqNVwlV3uQKBgHvlvXXb65k2csE5Q4J4vfN87KiSvF1CV1SjDUHcksSGdph15+gJ\n" +
"+Dx6V6mLMhVXvF6T6GdRNolLwt6x12MRUOAiFyL0B+L0dXNnATGzZO4RcFFfhVGX\n" +
"ziG6yO6Wf2q3BrCer4+fSn+dsYVtRrSiFIuUUu9Wyi3Ne2m8RFxF/LDfAoGATiBF\n" +
"jSwl5ZqZZf5OnaSLsksd9r5/VdZEHtRlOa2OQwvYmFbjm9vvj7P3V5YtZhvkF2AY\n" +
"B7IPKuokWuL82l0eAaPgzuhCLRSkEQExq0UzB407tr9TBW2d0p0++ayDYo4CNTDy\n" +
"36hQwTgvMgv6GrKFcnCkB0Lq/mNahrYMCX+G9mkCgYB8QXxOjfsKYcUF8XtJ6J3q\n" +
"Dxgz8Nh0L58KGPQkGQzPBmZfD6EZZRV9Lg0pC4vuFtxru0rckMYUNlmGFHWXhJxI\n" +
"WmYYc2DF82sqHXrwpGWDvAg4jQBMHwpHuB3TOXFrNR12iH0gyOYlPUYjLfFW/YVm\n" +
"bXkg5GmBl8jZxs9blQEZIg==\n" +
"-----END PRIVATE KEY-----";
private static final String KEY_PUBLIC = "-----BEGIN PUBLIC KEY-----\n" +
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAydWdzI6fBjHbv2JpBKvX\n" +
"HLgzZUR8iNONvVASglVNuaEdpELgv63kClWdF6aOvczLOfoBs+/7IgrYozyMlK+S\n" +
"af7Kw5uotbiiUpLj9kLHSGrtzYTCFF6W9gnCwbV8X6+g/666YVYf3jxBrd5BJ5Bz\n" +
"jR0r6RxFZSkmsXBtnLm0R388rA++V4dRGzHPMmEUvojgriVbQjckHgB2Z65MDwKc\n" +
"ZLLYtdPFzaPf41Ob7JJvJIxJL/bn5yN9QvA4BFIyLMboZ0soFX2upPYXO+mW4df8\n" +
"5w4q6yH0QG1gnYInKZo9AQID7/9zlsJSm/nrNSIqzU4R9ZwY2dLoN3OTt0DVOZ7a\n" +
"jwIDAQAB\n" +
"-----END PUBLIC KEY-----";
//待加密的原文字符串
private static final String TEST_STRING = "{\"extend\":\"测试\",\"product_id\":\"Test-888-CCH-20190521-01\",\"user_id_type\":\"PHONE\",\"user_id\":\"13899009900\",\"version\":\"1.0\"}";
private static final String SHA256_RSA = "SHA256withRSA";
public static void main(String[] args) {
//签名验证正向流程
String encodeResult = sgin(KEY_PRIVATE, TEST_STRING);
boolean verityResult = verify(KEY_PUBLIC, encodeResult, TEST_STRING);
System.out.print("签名结果 = " + encodeResult + "\n");
System.out.print("验签结果 = " + verityResult + "\n");
//签名内容被篡改的签名验证
String encodeResult2 = sgin(KEY_PRIVATE, TEST_STRING);
boolean verityResult2 = verify(KEY_PUBLIC, encodeResult2, TEST_STRING + "多余数据");
System.out.print("签名结果 = " + encodeResult2 + "\n");
System.out.print("验签结果 = " + verityResult2 + "\n");
}
//加密生成签名
private static String sgin(String privateKey, String contentToEncode) {
//把密钥的说明行和换行符全部去掉
privateKey = privateKey.replaceAll("-----END PRIVATE KEY-----", "").replaceAll("-----BEGIN PRIVATE KEY-----", "").replaceAll("\n", "");
try {
//将密钥转换成字节数组
byte[] b1 = Base64.getDecoder().decode(privateKey);
//将密钥进行编码
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(b1);
KeyFactory kf = KeyFactory.getInstance("RSA");
Signature privateSignature = Signature.getInstance(SHA256_RSA);
privateSignature.initSign(kf.generatePrivate(spec));
// 输入需要签名的内容
privateSignature.update(contentToEncode.getBytes("UTF-8"));
// 拿到签名后的字节数组
byte[] s = privateSignature.sign();
// 将签名后拿到的字节数组做一个Base64编码,以便以字符串的形式保存
return Base64.getEncoder().encodeToString(s);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException | InvalidKeySpecException | SignatureException | UnsupportedEncodingException e) {
e.printStackTrace();
}
return "";
}
//验证签名
private static boolean verify(String publicKey, String encodeResult, String contentToVerify) {
try {
publicKey = publicKey.replaceAll("-----END PUBLIC KEY-----", "").replaceAll("-----BEGIN PUBLIC KEY-----", "").replaceAll("\n", "");
byte[] b2 = Base64.getDecoder().decode(publicKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
Signature privateSignature = Signature.getInstance(SHA256_RSA);
privateSignature.initVerify(kf.generatePublic(new X509EncodedKeySpec(b2)));
privateSignature.update(contentToVerify.getBytes("UTF-8"));
byte[] verifyBytes = Base64.getDecoder().decode(encodeResult);
return privateSignature.verify(verifyBytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException | InvalidKeySpecException | SignatureException | UnsupportedEncodingException e) {
e.printStackTrace();
}
return false;
}
}
6.MD5加密
该加密工具先将字符串按utf-8字符集转换成字符数组,然后对字符数组使用MD5加密算法,再将加密得到的字符数组转换成十六进制字符串,工具类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
/**
* @author jingzhao
* @date 2021/06/02
*/
public class MD5Utils {
/**
* md5加密
*
* @param data
* @return
*/
public static String md5str(String data) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] ans = md5.digest(data.getBytes(StandardCharsets.UTF_8));
return StringHexUtils.bytesToHexString(ans).toUpperCase();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
/**
* 自己加的一个封装MD5加密的方法,输入一个Map,将Map中的键值对按字典序进行拼接,然后再加上key值进行加密
*
* @param params
* @param md5key
* @return
*/
public static String md5(Map<String,Object> params,String md5key) {
//将数据转移到TreeMap中
TreeMap<String, String> map = new TreeMap();
for (String name : params.keySet()) {
map.put(name, String.valueOf(params.get(name)));
}
StringBuilder sb = new StringBuilder();
for (String name : map.keySet()) {
sb.append(map.get(name));
}
sb.append(" ").append(md5key);
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] ans = md5.digest(sb.toString().getBytes(StandardCharsets.UTF_8));
return StringHexUtils.bytesToHexString(ans).toUpperCase();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
7.SHA512加密
与SHA256使用方法一模一样,MessageDigest本质上就是一个工厂类,根据不同算法名获取不同加密算法,工具类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class SHA512Utils {
public static String SHA256Str(String str) {
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance("SHA-512");
//str.getBytes("UTF-8")是将str字符串的每个字符转换成一个字节,得到一个字节数组。
messageDigest.update(str.getBytes("UTF-8"));
//经过加密得到的也是字节数组,再讲加密后的字节数组转换成十六进制字符串作为加密结果输出。
String encodeStr = StringHexUtils.bytesToHexString(messageDigest.digest());
return encodeStr;
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}