java密码加盐操作

1.MD5码的概述

MD5(Message Digest Algorithm 5)是一种广泛使用的哈希函数算法,用于将任意长度的数据转换成固定长度的散列值。它由Ronald Rivest于1991年设计,并被广泛应用于密码学和数据完整性校验等领域。MD5算法的输入可以是任意长度的数据,输出是一个128位(16字节)的散列值。该散列值通常表示为一个32位十六进制数字,例如:5d41402abc4b2a76b9719d911017c592。
MD5算法的核心原理是将输入数据分成一系列固定大小的数据块,并对每个数据块进行一系列复杂的运算操作,最终得到一个散列值。这个散列值具有以下特点:

固定长度:无论输入数据的大小,MD5算法的输出始终是128位(16字节)长。
唯一性:对于不同的输入数据,其散列值应当是唯一的,即不同的输入应当生成不同的散列值。
不可逆性:无法通过散列值逆推出原始输入数据。也就是说,即使散列值相同,无法确定其对应的具体输入数据。
高效性:MD5算法的计算速度相对较快,适用于快速生成散列值。

由于其设计上的弱点,MD5算法容易受到碰撞攻击(collision attack)或可使用彩虹表进行破解。碰撞攻击是指找到两个不同的输入数据,但它们却产生相同的MD5散列值的情况。
彩虹表(Rainbow Table)是一种用于加速密码破解的预计算技术。通过预先计算一系列可能的输入和其对应的散列值,然后通过比对查找输入值。

2.传统用户注册登录

通过用户在前端输入用户名和密码,后端得到用户名和密码后将其密码进行MD5编码后,存入sql表中;
待用户下次登陆时,同样输入用户名和密码,发送给后端,用户名找到sql中编码后的密码,因为MD5码具有不可逆性,故而需将输入的密码进行在次MD5加密,然后与sql中的密码进行比对,相同则返回登录成功。

3.密码加盐

密码加盐是一种增加密码安全性的技术。在密码加盐过程中,一个随机的字符串(称为盐)会与密码进行组合,然后对组合后的字符串进行哈希运算,最终存储在系统中。
盐的作用是为了使相同密码在哈希后产生不同的结果。这是因为即使两个用户使用了相同的密码,但由于他们的盐不同,最终生成的哈希值也会不同。这种方法的目的是增加密码破解的难度,即使攻击者获得了哈希值,他们也无法轻易地通过查找常见的明文密码来猜测原始密码。
密码加盐还能够防止使用彩虹表(rainbow table)进行暴力破解。彩虹表是一种预先计算并存储了密码哈希值和对应明文密码的表格,可以用于快速查找哈希值对应的明文密码。然而,由于每个用户都有唯一的盐值,攻击者无法事先生成包含所有可能盐值的彩虹表,从而增加了破解的难度。
总结来说,密码加盐是一种增加密码安全性的方法,通过随机盐值的引入,使相同密码在哈希后产生不同的结果,增加了密码破解的难度,并有效防止了彩虹表攻击。

4.代码举例

package com.example.demo.common;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import java.util.UUID;

/**
 * 密码工具类
 * 加盐加密 / 加盐解密
 */
public class PasswordTools {

    /**
     * 加盐加密
     *
     * @param password 明文密码
     * @return 加盐加密的密码
     */
    public static String encrypt(String password) {
        // 1.产生盐值
        String salt = UUID.randomUUID().toString().replace("-", "");
        // 2.使用(盐值+明文密码)得到加密的密码
        String finalPassword = DigestUtils.md5DigestAsHex((salt + password).getBytes());
        // 3.将盐值和加密的密码共同返回(合并盐值和加密密码)
        String dbPassword = salt + "$" + finalPassword;
        return dbPassword;
    }

    /**
     * 加盐加密
     *
     * @param password 明文密码
     * @param salt     盐值
     * @return 加盐加密的密码
     */
    public static String encrypt(String password, String salt) {
        // 1.使用(盐值+明文密码)得到加密的密码
        String finalPassword = DigestUtils.md5DigestAsHex((salt + password).getBytes());
        // 2.将盐值和加密的密码共同返回(合并盐值和加密密码)
        String dbPassword = salt + "$" + finalPassword;
        return dbPassword;
    }

    /**
     * 验证加盐加密密码
     *
     * @param password   明文密码(不一定对,需要验证明文密码)
     * @param dbPassword 数据库存储的密码(包含:salt+$+加盐加密密码)
     * @return true=密码正确
     */
    public static boolean decrypt(String password, String dbPassword) {
        boolean result = false;
        if (StringUtils.hasLength(password) && StringUtils.hasLength(dbPassword) &&
                dbPassword.length() == 65 && dbPassword.contains("$")) { // 参数正确
            // 1.得到盐值
            String[] passwrodArr = dbPassword.split("\\$");
            // 1.1 盐值
            String salt = passwrodArr[0];
            // 2.生成验证密码的加盐加密密码
            String checkPassword = encrypt(password, salt);
            if (dbPassword.equals(checkPassword)) {
                result = true;
            }
        }
        return result;
    }
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中使用MD5加密密码加盐可以通过以下步骤实现: 1. 导入相关的库和类。首先,需要导入java.security包中的MessageDigest类,该类提供了MD5加密的方法。 2. 创建一个方法来进行MD5加密。可以创建一个名为`encryptPassword`的方法,并传入两个参数:密码和盐值。方法的返回值应该是加密后的密码。 3. 在方法中对密码和盐值进行拼接。可以使用字符串的加法操作符将密码和盐值拼接在一起。 4. 创建一个MessageDigest对象,使用 getInstance("MD5")方法获取该对象。MessageDigest类提供了MD5加密算法的实现。 5. 使用MessageDigest对象对拼接后的字符串进行加密。可以调用`digest()`方法对字符串进行加密,该方法返回一个字节数组。 6. 将加密后的字节数组进行转换。可以使用`DatatypeConverter`类提供的`printHexBinary()`方法将字节数组转换成十六进制字符串。 7. 将转换后的字符串作为加密后的密码返回。 下面是一个示例代码片段: ```java import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MD5SaltExample { public static String encryptPassword(String password, String salt) { String saltedPassword = password + salt; try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] hashedPassword = md.digest(saltedPassword.getBytes()); // Convert byte array to hex string StringBuilder sb = new StringBuilder(); for (byte b : hashedPassword) { sb.append(String.format("%02x", b)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } public static void main(String[] args) { String password = "example"; String salt = "somesalt"; String encryptedPassword = encryptPassword(password, salt); System.out.println("Encrypted password: " + encryptedPassword); } } ``` 在上述代码中,我们首先将密码和盐值拼接在一起,然后使用MessageDigest类提供的`digest()`方法进行加密加密后的字节数组将被转换成十六进制字符串,并以字符串形式返回。在main方法中,我们将输入的密码和盐值传递给`encryptPassword`方法,并打印加密后的密码

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值