1.加密与解密
数据加密是计算机系统对信息进行保护的一种最可靠的办法。它利用密码技术对信息进行加密,实现信息隐蔽,从而起到保护信息的安全的作用。
加密
指通过加密算法和加密密钥将明文转变为密文
解密
指通过解密算法和解密密钥将密文恢复为明文。它的核心是密码学。
2.加密算法
加密算法分为 对称加密算法 、 非对称加密算法、散列算法,对比如下:
加密算法对比 - 光束云 - work100.net
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;/** *
Title: EncryptionUtils
*
Description:
*
Url: http://www.work100.net/training/monolithic-frameworks-mybatis.html
* * @author liuxiaojun * @date 2020-02-24 10:41 * ------------------- History ------------------- * * 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-lang3 和 org.springframework,因此我需要调整 iot-cloud-commons 的 pom.xml 文件,代码如下:
<?xml version="1.0" encoding="UTF-8"?>4.0.0net.work100.training.stage2 iot-cloud-dependencies 1.0.0-SNAPSHOT../iot-cloud-dependencies/pom.xml iot-cloud-commons jariot-cloud-commonsorg.springframework spring-webmvc org.apache.commons commons-lang3 org.slf4j slf4j-log4j12 ${slf4j.version}
5.实例源码
实例源码已经托管到如下地址:
- https://github.com/work100-net/training-stage2/tree/master/iot-cloud2
- https://gitee.com/work100-net/training-stage2/tree/master/iot-cloud2