且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Java单体应用 - 常用框架 - 08.MyBatis - 知识点:数据加密与密码

更新时间:2021-08-10 02:29:36

原文地址:http://www.work100.net/training/monolithic-frameworks-mybatis-encryption.html
更多教程:光束云 - 免费课程

知识点:数据加密与密码

序号 文内章节 视频
1 加密与解密 -
2 加密算法 -
3 密码实现方案 -
4 加密工具类 -
5 实例源码 -

请参照如上章节导航进行阅读

1.加密与解密

数据加密是计算机系统对信息进行保护的一种最可靠的办法。它利用密码技术对信息进行加密,实现信息隐蔽,从而起到保护信息的安全的作用。

加密

指通过加密算法加密密钥明文转变为密文

解密

指通过解密算法解密密钥密文恢复为明文。它的核心是密码学

2.加密算法

加密算法分为 对称加密算法非对称加密算法散列算法,对比如下:

加密算法 秘钥 算法举例
对称加密算法 加密与解密 密钥相同 DES3DESAES
非对称加密算法 加密与解密 密钥不同 RSADSA
散列算法 不需要密钥 MD5SHA-1SHA256

3.密码实现方案

明文存储

密码完全使用明文,将明文密码直接存储到数据中,此种方案存在很大安全风险,数据一旦泄露,用户的密码将一起被泄露出去。

密文存储

对密码明文进行加密,通常我们使用 散列算法 进行加密,将加密后的密文密码存储至数据库,这样即使发生数据泄露,外界也不知道明文密码。

但此种方案也存在一定的安全风险,有一种叫做 撞库 技术能够破解密文密码,即:当密文密码遭到泄露时,黑客可以通过网络上公开的密文与明文数据库进行密文对比,进而得到明文。

加盐加密

为了解决 撞库 的风险,我们对加密方案进行了升级,在加密时引入一个 干扰串(即:盐(salt)),该干扰串 随机生成

比如以 MD5 加密算法举例,其主要实现思路为:

密码密文 = MD5( 盐 + 密码明文)

4.加密工具类

我们提供了课程所使用的加密与解密的工具类,在项目 iot-cloud-commons 下新增一个 EncryptionUtils类,代码如下:

package net.work100.training.stage2.iot.cloud.commons.utils;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.DigestUtils;

/**
 * <p>Title: EncryptionUtils</p>
 * <p>Description: </p>
 * <p>Url: http://www.work100.net/training/monolithic-frameworks-mybatis.html</p>
 *
 * @author liuxiaojun
 * @date 2020-02-24 10:41
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-24   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public class EncryptionUtils {
    private static final int SALT_LENGTH = 6;
    private static final String SEPARATOR = "#";

    public enum EncryptionType {
        MD5("md5"),
        SHA256("sha256");

        private String type;

        EncryptionType(String type) {
            this.type = type;
        }

        public String getType() {
            return this.type;
        }

        public static EncryptionType getEncryptionType(String type) {
            if (StringUtils.isEmpty(type)) {
                return MD5;
            }
            for (EncryptionType encryptionType : EncryptionType.values()) {
                if (encryptionType.type.equalsIgnoreCase(type)) {
                    return encryptionType;
                }
            }
            return MD5;
        }
    }

    /**
     * 加密文本
     *
     * @param encryptionType 加密方式
     * @param sourceText     原文(区分大小写)
     * @return
     */
    public static String encryptText(EncryptionType encryptionType, String sourceText) {
        String encryptedText = "";
        switch (encryptionType) {
            case MD5:
                encryptedText = DigestUtils.md5DigestAsHex(sourceText.getBytes());
                break;
            case SHA256:
                break;
            default:
                encryptedText = DigestUtils.md5DigestAsHex(sourceText.getBytes());
                break;
        }
        return encryptedText;
    }

    /**
     * 加密密码
     *
     * @param encryptionType 加密方式
     * @param sourcePassword 明文密码
     * @return
     */
    public static String encryptPassword(EncryptionType encryptionType, String sourcePassword) {
        String salt = RandomStringUtils.randomAlphanumeric(SALT_LENGTH);
        sourcePassword = String.format("%s%s", sourcePassword, salt);
        String encryptedPassword = encryptText(encryptionType, sourcePassword);
        return String.format("%s%s%s%s%s", encryptionType.getType(), SEPARATOR, salt, SEPARATOR, encryptedPassword);
    }

    /**
     * 验证加密文本
     *
     * @param encryptionType 加密类型
     * @param sourceText     原文
     * @param encryptedText  密文
     * @return
     */
    public static boolean validateEncryptText(EncryptionType encryptionType, String sourceText, String encryptedText) {
        return encryptText(encryptionType, sourceText).equals(encryptedText);
    }

    /**
     * 验证密码
     *
     * @param sourcePassword    明文密码
     * @param encryptedPassword 加密后组合串
     * @return
     */
    public static boolean validateEncryptPassword(String sourcePassword, String encryptedPassword) {
        try {
            String[] split = encryptedPassword.split(SEPARATOR);
            EncryptionType encryptionType = EncryptionType.getEncryptionType(split[0]);
            String salt = split[1];
            encryptedPassword = split[2];
            sourcePassword = String.format("%s%s", sourcePassword, salt);
            return encryptText(encryptionType, sourcePassword).equals(encryptedPassword);
        } catch (Exception ex) {
            return false;
        }
    }
}

代码依赖了 org.apache.commons:commons-lang3org.springframework,因此我需要调整 iot-cloud-commonspom.xml 文件,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<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>

    <parent>
        <groupId>net.work100.training.stage2</groupId>
        <artifactId>iot-cloud-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../iot-cloud-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>iot-cloud-commons</artifactId>
    <packaging>jar</packaging>

    <name>iot-cloud-commons</name>
    <description></description>

    <dependencies>
        <!-- Spring Begin -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <!-- Spring End -->

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
    </dependencies>
</project>

5.实例源码

实例源码已经托管到如下地址:


上一篇:MyBatis 对象关系映射

下一篇:MyBatis 单表 CRUD 操作


如果对课程内容感兴趣,可以扫码关注我们的 公众号QQ群,及时关注我们的课程更新

Java单体应用 - 常用框架 - 08.MyBatis - 知识点:数据加密与密码
Java单体应用 - 常用框架 - 08.MyBatis - 知识点:数据加密与密码