• Java单体应用


    原文地址: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群,及时关注我们的课程更新

  • 相关阅读:
    poi 导出excel表格
    js 表单非空校验
    表格添加 点击添加增加一列
    date日期比较
    oralce 匿名块 练习
    SQL 入门
    Map集合&&异常处理&&file类
    Properties集合&&工具类FileUtils
    Java中Date类&&Calendar类
    jquery的基础
  • 原文地址:https://www.cnblogs.com/liuxiaojun/p/training-monolithic-frameworks-mybatis-encryption.html
Copyright © 2020-2023  润新知