一、对称加密
采用单钥密码的加密方法,同一个密钥可以同时用来加密和解密,这种加密方法称为对称加密,也称为单密钥加密。常用的对称加密算法:
- DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合;
- 3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高;
- AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高,支持128、192、256、512位密钥的加密;
- Blowfish
算法特征:
- 加密方和解密方使用同一个密钥;
- 加密解密的速度比较快,适合数据比较长时的使用;
- 密钥传输的过程不安全,且容易被破解,密钥管理也比较麻烦;
二、哈希算法
将任意长度的信息转换为较短的固定长度的值,通常其长度要比信息小得多,且算法不可逆。常见的哈希算法有:
- MD5(Message Digest Algorithm 5):是RSA数据安全公司开发的一种单向散列算法,非可逆,相同的明文产生相同的密文;
- SHA(Secure Hash Algorithm):可以对任意长度的数据运算生成一个160位的数值。其变种有SHA192,SHA256,SHA384等;
- CRC-32:主要用于提供校验功能;
算法特征:
① 输入一样,输出必然相同;
② 雪崩效应,输入的微小改变,将会引起结果的巨大变化;
③ 定长输出,无论原始数据多大,结果大小都是相同的;
④ 不可逆,无法根据特征码还原原来的数据;
三、非对称加密
非对称密钥加密也称为公钥加密,由一对公钥和私钥组成。公钥是从私钥提取出来的。可以用公钥加密,再用私钥解密,这种情形一般用于公钥加密;也可以用私钥加密,用公钥解密,常用于数字签名,因此非对称加密的主要功能就是加密和数字签名。
特征:
秘钥对,公钥(public key)和私钥(secret key)
主要功能:加密和签名
- 发送方用对方的公钥加密,可以保证数据的机密性(公钥加密);
- 发送方用自己的私钥加密,可以实现身份验证(数字签名);
常用的非对称加密算法:
- RSA
- ELGamal
公钥加密和数字签名的简单图解
1.
鲍勃有两把钥匙,一把是公钥,另一把是私钥。
2.
鲍勃把公钥送给他的朋友们----帕蒂、道格、苏珊----每人一把。
3.
苏珊要给鲍勃写一封保密的信。她写完后用鲍勃的公钥加密,就可以达到保密的效果。
4.
鲍勃收信后,用私钥解密,就看到了信件内容。这里要强调的是,只要鲍勃的私钥不泄露,这封信就是安全的,即使落在别人手里,也无法解密。
5.
鲍勃给苏珊回信,决定采用"数字签名"。他写完后先用Hash函数,生成信件的摘要(digest)。
6.
然后,鲍勃使用私钥,对这个摘要加密,生成"数字签名"(signature)。
7.
鲍勃将这个签名,附在信件下面,一起发给苏珊。
8.
苏珊收信后,取下数字签名,用鲍勃的公钥解密,得到信件的摘要。由此证明,这封信确实是鲍勃发出的。
9.
苏珊再对信件本身使用Hash函数,将得到的结果,与上一步得到的摘要进行对比。如果两者一致,就证明这封信未被修改过。
10.
复杂的情况出现了。道格想欺骗苏珊,他偷偷使用了苏珊的电脑,用自己的公钥换走了鲍勃的公钥。此时,苏珊实际拥有的是道格的公钥,但是还以为这是鲍勃的公钥。因此,道格就可以冒充鲍勃,用自己的私钥做成"数字签名",写信给苏珊,让苏珊用假的鲍勃公钥进行解密。
11.
后来,苏珊感觉不对劲,发现自己无法确定公钥是否真的属于鲍勃。她想到了一个办法,要求鲍勃去找"证书中心"(certificate authority,简称CA),为公钥做认证。证书中心用自己的私钥,对鲍勃的公钥和一些相关信息一起加密,生成"数字证书"(Digital Certificate)。
12.
鲍勃拿到数字证书以后,就可以放心了。以后再给苏珊写信,只要在签名的同时,再附上数字证书就行了。
13.
苏珊收信后,用CA的公钥解开数字证书,就可以拿到鲍勃真实的公钥了,然后就能证明"数字签名"是否真的是鲍勃签的。
14.
下面,我们看一个应用"数字证书"的实例:https协议。这个协议主要用于网页加密。
15.
首先,客户端向服务器发出加密请求。
16.
服务器用自己的私钥加密网页以后,连同本身的数字证书,一起发送给客户端。
17.
客户端(浏览器)的"证书管理器",有"受信任的根证书颁发机构"列表。客户端会根据这张列表,查看解开数字证书的公钥是否在列表之内。
18.
如果数字证书记载的网址,与你正在浏览的网址不一致,就说明这张证书可能被冒用,浏览器会发出警告。
19.
如果这张数字证书不是由受信任的机构颁发的,浏览器会发出另一种警告。
20.
如果数字证书是可靠的,客户端就可以使用证书中的服务器公钥,对信息进行加密,然后与服务器交换加密信息。
再详细的Https协议的原理,将在后续的博客中进行介绍。
加解密算法实现
AESUtil
package com.yj.encrypt.util;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class AESUtil {
/**
* 加密
*
* @param content
* 需要加密的内容
* @param password
* 加密密码
* @return
*/
public static String encrypt(String content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(byteContent);
String encryptResultStr = parseByte2HexStr(result);
return encryptResultStr; // 加密
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
/**
* 解密
*
* @param content
* 待解密内容
* @param password
* 解密密钥
* @return
*/
public static String decrypt(String content, String password) {
try {
byte[] decryptFrom = parseHexStr2Byte(content);
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(decryptFrom);
return new String(result); // 加密
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
/**
* 将二进制转换成16进制
*
* @param buf
* @return
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**
* 将16进制转换为二进制
*
* @param hexStr
* @return
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
}
DESUtil
package com.yj.encrypt.util;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class DESUtil {
/**
* 加密
*
* @param content
* 需要加密的内容
* @param secretKey
* 加密密码
* @return
*/
public static String encrypt(String content, String secretKey) {
try {
byte[] encryptionBytes = content.getBytes("UTF-8");
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(buildDesKey(secretKey));
// 创建一个密钥工厂,然后用它把DESKeySpec转换成
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密钥初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
// 执行加密操作
byte[] encryptionBase64Bytes = Base64.getEncoder().encode(cipher.doFinal(encryptionBytes));
// 转换为字符串返回
return new String(encryptionBase64Bytes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 解密
*
* @param content
* 需要解密的内容
* @param secretKey
* 解密密码
* @return
*/
public static String decrypt(String content, String secretKey) {
try {
byte[] decryptionbytes = Base64.getDecoder().decode(content);
// DES算法要求有一个可信任的随机数源
SecureRandom random = new SecureRandom();
// 创建一个DESKeySpec对象
DESKeySpec desKey = new DESKeySpec(buildDesKey(secretKey));
// 创建一个密钥工厂
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// 将DESKeySpec对象转换成SecretKey对象
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密钥初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, securekey, random);
// 开始解密操作
return new String(cipher.doFinal(decryptionbytes), "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/*
* 根据字符串生成密钥字节数组
*
* @param keyStr 密钥字符串
*
* @return
*
* @throws UnsupportedEncodingException
*/
public static byte[] buildDesKey(String keyStr) throws UnsupportedEncodingException {
byte[] key = new byte[24]; // 声明一个24位的字节数组,默认里面都是0
byte[] temp = keyStr.getBytes("UTF-8"); // 将字符串转成字节数组
/*
* 执行数组拷贝 System.arraycopy(源数组,从源数组哪里开始拷贝,目标数组,拷贝多少位)
*/
if (key.length > temp.length) {
// 如果temp不够24位,则拷贝temp数组整个长度的内容到key数组中
System.arraycopy(temp, 0, key, 0, temp.length);
} else {
// 如果temp大于24位,则拷贝temp数组24个长度的内容到key数组中
System.arraycopy(temp, 0, key, 0, key.length);
}
return key;
}
}
DES3Util(3DES加解密工具类)
package com.yj.encrypt.util;
import java.io.UnsupportedEncodingException;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class DES3Util {
// 定义加密算法,有DES、DESede(即3DES)、Blowfish
private static final String Algorithm = "DESede";
/**
* 加密
*
* @param content
* 需要加密的内容
* @param secretKey
* 加密密码
* @return
*/
public static String encrypt(String content, String secretKey) {
try {
byte[] encryptionBytes = content.getBytes("UTF-8");
SecretKey deskey = new SecretKeySpec(build3DesKey(secretKey), Algorithm); // 生成密钥
Cipher c1 = Cipher.getInstance(Algorithm); // 实例化负责加密/解密的Cipher工具类
c1.init(Cipher.ENCRYPT_MODE, deskey); // 初始化为加密模式
return new String(Base64.getEncoder().encode(c1.doFinal(encryptionBytes)));
} catch (java.security.NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (javax.crypto.NoSuchPaddingException e2) {
e2.printStackTrace();
} catch (java.lang.Exception e3) {
e3.printStackTrace();
}
return null;
}
/**
* 解密
*
* @param content
* 需要解密的内容
* @param secretKey
* 解密密码
* @return
*/
public static String decrypt(String content, String secretKey) {
try {
byte[] decryptionbytes = Base64.getDecoder().decode(content);
SecretKey deskey = new SecretKeySpec(build3DesKey(secretKey), Algorithm);
Cipher c1 = Cipher.getInstance(Algorithm);
c1.init(Cipher.DECRYPT_MODE, deskey); // 初始化为解密模式
return new String(c1.doFinal(decryptionbytes));
} catch (java.security.NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (javax.crypto.NoSuchPaddingException e2) {
e2.printStackTrace();
} catch (java.lang.Exception e3) {
e3.printStackTrace();
}
return null;
}
/*
* 根据字符串生成密钥字节数组
*
* @param keyStr 密钥字符串
*
* @return
*
* @throws UnsupportedEncodingException
*/
public static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException {
byte[] key = new byte[24]; // 声明一个24位的字节数组,默认里面都是0
byte[] temp = keyStr.getBytes("UTF-8"); // 将字符串转成字节数组
/*
* 执行数组拷贝 System.arraycopy(源数组,从源数组哪里开始拷贝,目标数组,拷贝多少位)
*/
if (key.length > temp.length) {
// 如果temp不够24位,则拷贝temp数组整个长度的内容到key数组中
System.arraycopy(temp, 0, key, 0, temp.length);
} else {
// 如果temp大于24位,则拷贝temp数组24个长度的内容到key数组中
System.arraycopy(temp, 0, key, 0, key.length);
}
return key;
}
}
对称加密Test文件
package com.yj.encrypt;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.yj.encrypt.util.AESUtil;
import com.yj.encrypt.util.DES3Util;
import com.yj.encrypt.util.DESUtil;
//对称加密
public class SymmetricEncrypt {
private Logger log = LoggerFactory.getLogger(this.getClass());
public static String content = "我的加密内容";
public static String secretKey = "mykey";
@Test
public void DES() throws Exception {
String result = DESUtil.encrypt(content, secretKey);
log.info("DES加密结果:" + result);
result = DESUtil.decrypt(result, secretKey);
log.info("DES解密结果:" + result);
}
@Test
public void DES3() throws Exception {
String result = DES3Util.encrypt(content, secretKey);
log.info("3DES加密结果:" + result);
result = DES3Util.decrypt(result, secretKey);
log.info("3DES解密结果:" + result);
}
@Test
public void AES() throws Exception {
String result = AESUtil.encrypt(content, secretKey);
log.info("AES加密后:" + result);
result = AESUtil.decrypt(result,secretKey);
log.info("AES解密后:" + result);
}
// base不属于对称加密,暂时将它放在这里
// jdk实现,sun.misc包是Sun公司提供给内部使用的专用API,在java API文档中我们看不到任何有关BASE64影子,不建议使用
// 此处我们采用apache实现
@Test
public void BASE64() throws Exception {
String sourceStr = "123456";
org.apache.tomcat.util.codec.binary.Base64 base = new org.apache.tomcat.util.codec.binary.Base64();
String result = base.encodeAsString(sourceStr.getBytes("UTF-8"));
log.info("BASE64加密结果:" + result);
byte[] decodeByte = base.decode(result);
result = new String(decodeByte);
log.info("BASE64解密结果:" + result);
}
}
非对称加密Test文件
package com.yj.encrypt;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import javax.crypto.spec.DHParameterSpec;
import org.apache.tomcat.util.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//非对称加密
public class AsymmetricEncrypt {
private Logger log = LoggerFactory.getLogger(this.getClass());
public static String content = "我的加密内容";
RSAPublicKey rsaPublicKey;
RSAPrivateKey rsaPrivateKey;
PublicKey elGamalPublicKey;
PrivateKey elGamalPrivateKey;
@Before
public void init() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);// 密钥长度为64的整数倍,最大是65536
KeyPair keyPair = keyPairGenerator.generateKeyPair();
rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
log.info("RSA公钥:" + Base64.encodeBase64String(rsaPublicKey.getEncoded()));
log.info("RSA私钥:" + Base64.encodeBase64String(rsaPrivateKey.getEncoded()));
log.info("==RSA结束==ELGamal开始==");
//JAVA7不支持,pom文件需引入BouncyCastle
Security.addProvider(new BouncyCastleProvider());
AlgorithmParameterGenerator apg = AlgorithmParameterGenerator.getInstance("ElGamal");
apg.init(256);
AlgorithmParameters params = apg.generateParameters();
DHParameterSpec dhParams = params.getParameterSpec(DHParameterSpec.class);
KeyPairGenerator keyPairGene = KeyPairGenerator.getInstance("ElGamal");
keyPairGene.initialize(dhParams, new SecureRandom());
KeyPair ELGamalKeyPair = keyPairGene.generateKeyPair();
elGamalPublicKey = ELGamalKeyPair.getPublic();
elGamalPrivateKey = ELGamalKeyPair.getPrivate();
log.info("ELGamal公钥:" + Base64.encodeBase64String(elGamalPublicKey.getEncoded()));
log.info("ELGamal私钥:" + Base64.encodeBase64String(elGamalPrivateKey.getEncoded()));
}
@Test
public void RSA1() throws Exception {
log.info("私钥加密,公钥解密");
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(content.getBytes());
log.info("RSA私钥加密:" + Base64.encodeBase64String(result));
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
result = cipher.doFinal(result);
log.info("RSA公钥解密:" + new String(result));
}
@Test
public void RSA2() throws Exception {
log.info("公钥加密,私钥解密");
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(content.getBytes());
log.info("RSA公钥加密:" + Base64.encodeBase64String(result));
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
result = cipher.doFinal(result);
log.info("RSA私钥解密:" + new String(result));
}
/*
* 只有公钥加密,私钥解密
* */
@Test
public void Elgamal() throws Exception {
log.info("公钥加密,私钥解密");
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(elGamalPublicKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("ELGamal");
PublicKey elGamalPublicKey = (PublicKey) keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("ELGamal", "BC");
cipher.init(Cipher.ENCRYPT_MODE, elGamalPublicKey);
byte[] result = cipher.doFinal(content.getBytes());
log.info("ELGamal公钥加密:" + Base64.encodeBase64String(result));
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(elGamalPrivateKey.getEncoded());
keyFactory = KeyFactory.getInstance("ELGamal");
PrivateKey elGamalPrivateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
cipher.init(Cipher.DECRYPT_MODE, elGamalPrivateKey);
result = cipher.doFinal(result);
log.info("ELGamal私钥解密:" + new String(result));
}
}
Hash加密Test文件
package com.yj.encrypt;
import java.security.MessageDigest;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//HASH加密
public class HashEncrypt {
private Logger log = LoggerFactory.getLogger(this.getClass());
public static String content = "123456";
@Test
public void MD5() throws Exception {
String sourceStr = "123456";
String result;
// 定义一个16进制char数组,取每一个byte前后四位对应char的十六进制数值
char HEX[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
byte[] sourceByte = sourceStr.getBytes("UTF-8");
// 获得MD5摘要算法的 MessageDigest 对象
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
messageDigest.update(sourceByte);
// 获得密文
byte[] md = messageDigest.digest();
// 把密文转换成十六进制的字符串形式
int j = md.length;
char buf[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[k++] = HEX[byte0 >>> 4 & 0xf];
buf[k++] = HEX[byte0 & 0xf];
}
result = new String(buf);
log.info("MD5加密结果:" + result);
}
@Test
public void SHA() throws Exception {
String sourceStr = "123456";
String result;
char HEX[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
messageDigest.update(sourceStr.getBytes("UTF-8"));
byte[] md = messageDigest.digest();
int j = md.length;
char buf[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[k++] = HEX[byte0 >>> 4 & 0xf];
buf[k++] = HEX[byte0 & 0xf];
}
result = new String(buf);
log.info("SHA加密结果:" + result);
}
}
pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yj</groupId>
<artifactId>Encrypt</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Encrypt</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.17.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>
</dependencies>
</project>