Java方式通实现用户密码加密
目录
一、概念
1.消息摘要算法
消息摘要算法的特征是加密过程不需要秘钥
,并且加密的数据无法被解密
。任何消息经过散列函数
处理后,都会获得唯一的散列值,这一过程称为“消息摘要”。
消息摘要算法最著名的是MD5算法和SHA-1算法及其变体
。
MD5算法长度为128位(16字节),SHA-1算法长度为160位(20字节),SHA-256算法长度为256位(64字节)。
消息摘要函数是单向函数,只能正向求得密文,无法反向求明文信息
。
单向加密,即加密之后不能解密
,一般用于数据验证。
2.常见的加密方式有
- MD5加密
- SHA加密(SHA-1、SHA-256)
- base64加密
- pbkdf2&sha256加密
二、加密算法实现
idea新建maven项目:
1.Java实现MD5加密(单向加密)
java没有实现MD5解密操作
,但是有些网站可以完成解密
MD5加密的三种方式:
- 借助apache工具类DigesUtils实现(推荐使用)
- 使用JDK自带的java.security.MessageDigest下的MessageDigest类
- Spring核心包(Spring Boot 自带MD5加密)
说明:都是返回长度为32位的16进制字符串(小写)。
MD5 是哈希散列算法(也称摘要算法),对于 MD5 而言,有两个特性是很重要的,
明文数据经过散列以后的值是定长的;
是任意一段明文数据,经过散列以后,其结果必须永远是不变的。
1.1 MD5加密方式1:借助apache工具类DigesUtils实现(推荐使用)
此方式需要 安装 commons-codec 依赖
<!--commons-codec 依赖-->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
import org.apache.commons.codec.digest.DigestUtils;
/**
* MD5加密方式一:借助apache工具类DigesUtils实现(推荐使用)
*
* 此方式需要 安装 commons-codec 依赖
* @param str 待加密字符串
* @return 16进制加密字符串(32位MD5码)
*/
public static String encryptToMD5(String str){
//MD5 加密,返回 32 位
return DigestUtils.md5Hex(str);
}
org.apache.commons.codec.digest.DigestUtils 类:
1.2 MD5加密方式2:使用JDK自带的java.security.MessageDigest下的MessageDigest类
/**
* MD5加密方式二:使用JDK自带的java.security.MessageDigest下的MessageDigest类
* @param str 待加密字符串
* @return 16进制加密字符串(32位MD5码)
*/
public static String encrypt2ToMD5(String str) throws NoSuchAlgorithmException {
//MD5 加密(使用MD5算法)
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] md5Bytes = md.digest(str.getBytes(StandardCharsets.UTF_8));
//为了使用方便,将输出值转换为十六进制保存
return bytesToHexString(md5Bytes);
}
/**
* 将输出值转换为十六进制保存
* @param bytes
* @return
*/
public static String bytesToHexString(byte[] bytes) {
StringBuilder stringBuilder = new StringBuilder();
if (bytes == null || bytes.length <= 0) {
return null;
}
for (byte aByte : bytes) {
int v = aByte & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
1.3 MD5加密方式3: Spring核心包(Spring Boot 自带MD5加密)
安装spring 核心包 依赖
<!--spring 核心包 依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.2</version>
</dependency>
org.springframework.util.DigestUtils.md5DigestAsHex
/**
* MD5加密方式三:Spring核心包(Spring Boot 自带MD5加密)
* @param str 待加密字符串
* @return 16进制加密字符串(32位MD5码 小写)
*/
public static String encrypt3ToMD5(String str){
return org.springframework.util.DigestUtils.md5DigestAsHex(str.getBytes(StandardCharsets.UTF_8));
}
1.4 测试
MD5工具类 完整代码:
package utils;
import org.apache.commons.codec.digest.DigestUtils;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* ND5加密
* @author qzz
*/
public class MD5Util {
/**
* MD5加密方式一:借助apache工具类DigesUtils实现(推荐使用)
*
* 此方式需要 安装 commons-codec 依赖
* @param str 待加密字符串
* @return 16进制加密字符串(32位MD5码)
*/
public static String encryptToMD5(String str){
//MD5 加密,返回 32 位
return DigestUtils.md5Hex(str);
}
/**
* MD5加密方式二:使用JDK自带的java.security.MessageDigest下的MessageDigest类
* @param str 待加密字符串
* @return 16进制加密字符串(32位MD5码)
*/
public static String encrypt2ToMD5(String str) throws NoSuchAlgorithmException {
//MD5 加密(使用MD5算法)
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] md5Bytes = md.digest(str.getBytes(StandardCharsets.UTF_8));
//为了使用方便,将输出值转换为十六进制保存
return bytesToHexString(md5Bytes);
}
/**
* MD5加密方式三:Spring核心包(Spring Boot 自带MD5加密)
* @param str 待加密字符串
* @return 16进制加密字符串(32位MD5码 小写)
*/
public static String encrypt3ToMD5(String str){
return org.springframework.util.DigestUtils.md5DigestAsHex(str.getBytes(StandardCharsets.UTF_8));
}
/**
* 将输出值转换为十六进制保存
* @param bytes
* @return
*/
public static String bytesToHexString(byte[] bytes) {
StringBuilder stringBuilder = new StringBuilder();
if (bytes == null || bytes.length <= 0) {
return null;
}
for (byte aByte : bytes) {
int v = aByte & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
public static void main(String[] args) throws NoSuchAlgorithmException {
String str="123456";
System.out.println("MD5待加密字符串:"+str);
String md5Str=MD5Util.encryptToMD5(str);
System.out.println("方式一:MD5加密结果:"+md5Str);
String md5Str2=MD5Util.encrypt2ToMD5(str);
System.out.println("方式二:MD5加密结果:"+md5Str2);
String md5Str3=MD5Util.encrypt3ToMD5(str);
System.out.println("方式三:MD5加密结果:"+md5Str3);
}
}
执行结果:
"D:\Program Files\Java\jdk1.8.0_40\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.1.3\lib\idea_rt.jar=62529:C:\Program Files\JetBrains\IntelliJ IDEA 2021.1.3\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_40\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8.0_40\jre\lib\rt.jar;F:\study-project\password-validate\target\classes;D:\mvnrepository\commons-codec\commons-codec\1.15\commons-codec-1.15.jar;D:\mvnrepository\org\springframework\boot\spring-boot-starter-web\2.7.2\spring-boot-starter-web-2.7.2.jar;D:\mvnrepository\org\springframework\boot\spring-boot-starter\2.7.2\spring-boot-starter-2.7.2.jar;D:\mvnrepository\org\springframework\boot\spring-boot\2.7.2\spring-boot-2.7.2.jar;D:\mvnrepository\org\springframework\boot\spring-boot-autoconfigure\2.7.2\spring-boot-autoconfigure-2.7.2.jar;D:\mvnrepository\org\springframework\boot\spring-boot-starter-logging\2.7.2\spring-boot-starter-logging-2.7.2.jar;D:\mvnrepository\ch\qos\logback\logback-classic\1.2.11\logback-classic-1.2.11.jar;D:\mvnrepository\ch\qos\logback\logback-core\1.2.11\logback-core-1.2.11.jar;D:\mvnrepository\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;D:\mvnrepository\org\apache\logging\log4j\log4j-to-slf4j\2.17.2\log4j-to-slf4j-2.17.2.jar;D:\mvnrepository\org\apache\logging\log4j\log4j-api\2.17.2\log4j-api-2.17.2.jar;D:\mvnrepository\org\slf4j\jul-to-slf4j\1.7.36\jul-to-slf4j-1.7.36.jar;D:\mvnrepository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\mvnrepository\org\springframework\spring-core\5.3.22\spring-core-5.3.22.jar;D:\mvnrepository\org\springframework\spring-jcl\5.3.22\spring-jcl-5.3.22.jar;D:\mvnrepository\org\yaml\snakeyaml\1.30\snakeyaml-1.30.jar;D:\mvnrepository\org\springframework\boot\spring-boot-starter-json\2.7.2\spring-boot-starter-json-2.7.2.jar;D:\mvnrepository\com\fasterxml\jackson\core\jackson-databind\2.13.3\jackson-databind-2.13.3.jar;D:\mvnrepository\com\fasterxml\jackson\core\jackson-annotations\2.13.3\jackson-annotations-2.13.3.jar;D:\mvnrepository\com\fasterxml\jackson\core\jackson-core\2.13.3\jackson-core-2.13.3.jar;D:\mvnrepository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.13.3\jackson-datatype-jdk8-2.13.3.jar;D:\mvnrepository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.13.3\jackson-datatype-jsr310-2.13.3.jar;D:\mvnrepository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.13.3\jackson-module-parameter-names-2.13.3.jar;D:\mvnrepository\org\springframework\boot\spring-boot-starter-tomcat\2.7.2\spring-boot-starter-tomcat-2.7.2.jar;D:\mvnrepository\org\apache\tomcat\embed\tomcat-embed-core\9.0.65\tomcat-embed-core-9.0.65.jar;D:\mvnrepository\org\apache\tomcat\embed\tomcat-embed-el\9.0.65\tomcat-embed-el-9.0.65.jar;D:\mvnrepository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.65\tomcat-embed-websocket-9.0.65.jar;D:\mvnrepository\org\springframework\spring-web\5.3.22\spring-web-5.3.22.jar;D:\mvnrepository\org\springframework\spring-beans\5.3.22\spring-beans-5.3.22.jar;D:\mvnrepository\org\springframework\spring-webmvc\5.3.22\spring-webmvc-5.3.22.jar;D:\mvnrepository\org\springframework\spring-aop\5.3.22\spring-aop-5.3.22.jar;D:\mvnrepository\org\springframework\spring-context\5.3.22\spring-context-5.3.22.jar;D:\mvnrepository\org\springframework\spring-expression\5.3.22\spring-expression-5.3.22.jar" utils.MD5Util
MD5待加密字符串:123456
方式一:MD5加密结果:e10adc3949ba59abbe56e057f20f883e
方式二:MD5加密结果:e10adc3949ba59abbe56e057f20f883e
方式三:MD5加密结果:e10adc3949ba59abbe56e057f20f883e
Process finished with exit code 0
MD5 曾一度被认为是非常安全的。但是 MD5 也不会完全不重复,从概率来说 16 的 32 次方遍历后至少出现两个相同的 MD5 值。
以 Google 公司为例,Google 公司明确指出不建议再使用 MD5 算法,而使用 SHA256 算法替代
。
2.Java实现SHA256 加密(单向加密)
SHA-256 算法单向 Hash
函数是密码学和信息安全领域中的一个非常重要的基本算法,它是把任意长的消息转化为较短的、固定长度的消息摘要的算法
。SHA-256 算法是 SHA
算法族中的一员,由美国国家安全局(NSA)所设计,并由美国国家标准与技术研究院(NIST)发布;是美国的政府标准。它的前辈还有 SHA-1。
随着密码学<small>(破解)</small>的发展,美国政府计划从 2010 年起不再使用 SHA-1,全面推广使用 SHA-256 和 SHA-512 等加密算法
。
对于任意长度的消息,SHA256 都会产生一个 256bit 长的哈希值,称作消息摘要
。这个摘要相当于是个长度为 32 个字节的数组,通常用一个长度为 64 的十六进制字符串来表示。
SHA256 加密实现方式:
- 加密方式一:借助apache工具类DigesUtils实现(推荐使用)
- 加密方式二:使用JDK自带的java.security.MessageDigest下的MessageDigest类
2.1 SHA256 加密方式1:借助apache工具类DigesUtils实现(推荐使用)
import org.apache.commons.codec.digest.DigestUtils;
/**
* 加密方式一:借助apache工具类DigesUtils实现(推荐使用)
*
* 此方式需要 安装 commons-codec 依赖
* @param str 待加密字符串
* @return 16进制加密字符串(64位)
*/
public static String encryptToSHA256(String str){
//SHA-256 加密,返回 64 位
return DigestUtils.sha256Hex(str.getBytes(StandardCharsets.UTF_8));
}
2.2 SHA256 加密方式2:使用JDK自带的java.security.MessageDigest下的MessageDigest类
/**
* 加密方式二:使用JDK自带的java.security.MessageDigest下的MessageDigest类
*
* 此方式需要 安装 commons-codec 依赖
* @param str 待加密字符串
* @return 16进制加密字符串(64位)
*/
public static String encrypt2ToSHA256(String str) throws NoSuchAlgorithmException {
//SHA-256 加密,返回 64 位
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] md5Bytes = md.digest(str.