一、密码算法分为:对称加密,非对称加密,摘要算法,数字签名,数字证书
重点说的是摘要算法中MD5和SHA-256算法,SHA-256和MD5用法相似。
二、MD5具有以下特点:
1.不可逆性:MD5 是单向哈希函数,意味着无法从哈希值反向推导出原始输入。
2.相同输入产生相同输出:对于相同的输入数据,始终会生成相同的 MD5 哈希值
3.快速计算:MD5 的计算速度相对较快,使其在实际应用中非常高效
4.冲突概率:当输入的数据量远大于 MD5 哈希值的空间时,必然会出现不同的输入数据生成相同的哈希值的情况。这意味着不同的输入数据可能会产生相同的哈希值
5.容易受到碰撞攻击:攻击者可以通过两个不同的输入数据,是他们生成相同的MD5哈希值。
三、加盐:
加盐可以增加密码安全性。盐值是一个随机生成的唯一字符串,与密码结合后进行哈希运算,然后将盐值与哈希结果一起存储在数据库中。通过使用盐值,即使两个用户的密码相同,由于每个用户都有独立的盐值,最终存储的哈希值也会不同。这样即使攻击者获得了数据库的哈希值,也很难通过彩虹表等方式进行破解。
四、简单说明使用
用一个简单的例子来说明两种算法的简单使用以及展示遇到的问题。
在web项目中,关于用户注册和登录可以采用两种方式进行加密:
①密码传给servlet类处理前,使用js技术将密码加密,(在使用时得先获取相应的js文件)
②servlet类在接收到密码后再进行加密
使用①需要获取md5.js文件:通过Paj's Home: Cryptography: JavaScript MD5 (pajhome.org.uk)https://pajhome.org.uk/crypt/md5/
----> Script(more) -----> jshash-2.2.zip下载。下载好的目录如下:
这是外部js文件引入到你所需要的包中就行。
MD5算法(js)
login.jsp页面--------------------------------------------------------------------------
<%@ page pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>SHA-256加密示例</title>
</head>
<body>
<h1>SHA-256加密示例</h1>
<form action="processForm" method="get">
用户名:
<input type="text" id="username" name="username"><br>
密码:
<input type="password" id="password" name="password"><br><br>
<input type="hidden" id="encryptedPassword" name="encryptedPassword"> <!-- 用于存储加密后的密码 -->
<input type="submit" value="加密密码并提交" οnclick="encryptPassword()">
</form>
<%--<script src="js/sha256.js"></script>--%>
<script src="js/md5.js"></script> <!-- 引入SHA-256加密算法的JavaScript库 -->
<script>
function encryptPassword() {
let passwordInput = document.getElementById("password"); // 获取密码输入框
let password = passwordInput.value; // 获取密码值
//加盐操作
//let salt = "abc";
//let encryptedPassword =hex_md5(password+"abc");
let encryptedPassword =hex_md5(password); // 使用SHA-256算法对密码进行加密
// passwordInput.value = ""; // 清空密码框,以防止明文密码在DOM中存储
document.getElementById("encryptedPassword").value = encryptedPassword; // 将加密后的密码设置到隐藏字段中
}
</script>
</body>
</html>
MyServlet类如下-------------------------------------------------------------------------
import java.io.*; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; @WebServlet("/processForm") public class MyServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取用户输入的加密后的密码 String encryptedPassword = request.getParameter("encryptedPassword"); // 输出加密后的密码 response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.println("<html><body>"); out.println("加密后的密码:" + encryptedPassword); out.println("</body></html>"); }} 运行截图:
let salt = "abc"; let encryptedPassword =hex_md5(password+"abc");
第二种方法的实现:
index.jsp-----------------------------------------------------------------------------------------------------------------
<%@page pageEncoding="utf-8"%> <!DOCTYPE html> <html> <head> <title>MD5加密示例</title> </head> <body> <h1>MD5加密示例</h1> <form action="processForm" method="get"> 密码: <input type="password" name="password"><br><br> <input type="submit" value="加密密码"> </form> </body> </html>
MyServlet如下-------------------------------------------------------------------------------------------------------------
import java.io.*; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; @WebServlet("/processForm") public class MyServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取用户输入的原始密码 String password = request.getParameter("password"); // 使用MD5算法进行密码加密 String encryptedPassword = md5(password); // 输出加密后的密码 response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.println("<html><body>"); out.println("加密后的密码:" + encryptedPassword); out.println("</body></html>"); } private String md5(String password) { // 创建 MessageDigest 实例并指定使用 MD5 算法 MessageDigest md = null; try { md = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } // 将密码转换为字节数组并进行加密处理 byte[] messageDigest = md.digest(password.getBytes()); // 将字节数组转换为十六进制字符串 BigInteger no = new BigInteger(1, messageDigest); String encryptedPassword = no.toString(16); // 如果生成的十六进制字符串长度不足 32 位,前面补零 while (encryptedPassword.length() < 32) { encryptedPassword = "0" + encryptedPassword; } return encryptedPassword; } }
运行截图:
String salt = "abc"; byte[] messageDigest = md.digest((password+salt).getBytes());