密码加密解密之路

1.背景

做数据采集,客户需要把他们那边的数据库连接信息存到我们系统里,那我们系统就要尽可能的保证这部分数据安全,不被盗。

2.我的思路

1.需要加密的地方有两处,一个是新增的时候前端传给后端的时候,一个是存到数据库

2.与前端交互时的加密方式肯定和存到数据库的加密方式不同(为了安全)

3.接收前端传值,这块好说,跟前端约定一个加密方式,约定一个盐

4.存到数据库怎么加密解密

麻烦得点就在于存到数据库这里,

我是针对每一条数据都会生成一个uuid,然后nacos配置文件中还有一个盐salt

然后我把uuid和salt用特殊符号拼接之后,再进行一次加密形成最终盐 finalSalt

用finalSalt对密码进行加密,把密文密码存到数据库

如果用户对密码进行修改,那就重新生成一个uuid,再重新加密,存储密文

之所以设计这么麻烦,就是增加解密得困难度,想要明文,只有同时拿到数据库数据,nacos配置,以及我的java代码,才能解密,尽可能保障密码得安全性

5.密码可为空

这一点我是纠结了一会,因为在产品设计上密码是可为空得,如果我不把密码返回给前端,那前端保存得时候,如果用户没修改密码,前端上传给我得也会是空,那这个时候我就不知道到底是用户把密码改为空了,还是说他根本没有动密码这个文本框

所以我就把密文密码返回了,让他保存到时候再按照前后端约定加密传输给我,

我接收到之后先按照前后端约定得解密,再去和数据里边密文对比,

如果一致,说明没改,

如果不一致,说明修改了,并且解密出来的是明文密码,我会对明文密码按照4中说的再进行加密

但是把密文密码传给前端始终是个不太安全得事情

我后来想到一点,前端是可以识别到,用户是否动过密码这个文本框得

那我就不把密码返回给前端了

可以让前端给我一个标识,true,就代表动过文本框,

如果现在上传得密码为空,且动过文本框,那我就直接把密码字段保存为空即可。

如果现在上传得密码为空,但是false,没动过文本框,那我就不更新密码这个字段

如果现在上传密码不为空,那就不管true还是false了,密码肯定修改了,就先按照前后端解密再按照数据库加密即可

3.加解密工具类

这是针对数据库那一部分

博客上是前后端约定的那一部分

【精选】java前后端加密解密crypto-js_java crypto-CSDN博客


import org.apache.commons.codec.binary.Base64;
import org.springframework.util.StringUtils;import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;/*** @Description: 加密解密* @Version 1.0*/
public class SecretUtil {/*** 用uuid加密** @param UUID* @param salt     盐 从nacos配置中取值* @param password 明文密码* @return*/public static String encryptUUID(String UUID, String salt, String password) {if (!StringUtils.hasText(UUID) || !StringUtils.hasText(salt) || !StringUtils.hasText(password)) {return null;}//先把uuid和salt再进行一次加密String concat = UUID.concat(salt);byte[] bytes = base64Encrypt(concat);//再对明文密码进行加密return encrypt(password, bytes);}/*** UUID解密** @param UUID* @param salt     盐 从nacos配置中取值* @param password 密文密码* @return*/public static String decryptUUID(String UUID, String salt, String password) {if (!StringUtils.hasText(UUID) || !StringUtils.hasText(salt) || !StringUtils.hasText(password)) {return null;}//先把uuid和salt再进行一次加密String concat = UUID.concat(salt);byte[] bytes = base64Encrypt(concat);//再对明文密码进行加密return decrypt(password, bytes);}/*** base64加密** @param content 待加密内容* @return byte[]*/public static byte[] base64Encrypt(final String content) {return java.util.Base64.getEncoder().encode(content.getBytes());}/*** base64解密** @param encoderContent 已加密内容* @return byte[]*/public static byte[] base64Decrypt(final byte[] encoderContent) {return java.util.Base64.getDecoder().decode(encoderContent);}/*** 加密** @param data  待加密内容* @param bytes 盐的base64* @return*/public static String encrypt(String data, byte[] bytes) {byte[] dataByte = data.getBytes(StandardCharsets.UTF_8);try {KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");secureRandom.setSeed(bytes);//这个128要特别注意  对长度有要求的keyGenerator.init(128, secureRandom);SecretKey secretKey = keyGenerator.generateKey();Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] encrypted = cipher.doFinal(dataByte);// 加密return java.util.Base64.getEncoder().encodeToString(encrypted);} catch (Exception e) {throw new RuntimeException(e);}}/*** 解密** @param data  待解密内容* @param bytes 盐的base64* @return*/public static String decrypt(String data, byte[] bytes) {try {KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");secureRandom.setSeed(bytes);//这个128要特别注意  对长度有要求的keyGenerator.init(128, secureRandom);SecretKey secretKey = keyGenerator.generateKey();Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(secretKey.getEncoded(), "AES"));//采用base64算法进行转码,避免出现中文乱码byte[] encryptBytes = Base64.decodeBase64(data);byte[] decryptBytes = cipher.doFinal(encryptBytes);return new String(decryptBytes);} catch (Exception e) {throw new RuntimeException(e);}}}

4.代码混淆

这块可以不看,是中间调研,走过的一个弯路

因为java的class文件可以反编译,所以我想让编译之后的代码变成01001那种无法识别的语言

但是发现java代码混淆并不能达成这个效果

但是毕竟走了一天弯路,还是记录下吧

4.1先看效果

4.2再上代码

从这下载吧

https://download.csdn.net/download/qq_35653822/88554123

里边有个字典,可以实现把包名,类名,变量名混淆为0o00o这种方式

5.不可逆算法

目前接触到的,存登录密码是不可逆算法,用的是security自带的加密

security提供了match方法,可以对比输入的密码和数据库中是否一致,返回true或者false,但是不提供解密方法

除非管理员可以一键重置用户的密码,把用户密码重置成初始化默认密码

存数据库里边的长这样,谁也看不出来存的是啥

 这种方法固然安全,但是对于我们1中说的需求,不适合这种算法,因为我们使用对方数据库的时候肯定要获取这个密码进行连接

    public static String irreversibleEncrypt(String password) {BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();//加密  每次调用加密方法 返回的结果都不同return passwordEncoder.encode(password);}/*** 对比* 不可逆算法 不能解密 只能对比** @param oldPassword     未加密密码 如123456* @param requestPassword 加密后的密码* @return*/public static boolean irreversibleMatch(String oldPassword, String requestPassword) {BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();//对比return passwordEncoder.matches(oldPassword, requestPassword);}

6.不对称算法

这个什么时候使用就看具体场景吧

7.keystore

Java密码术 - 存储密钥( Storing keys)_学习Java密码学|WIKI教程

这个同事调研过,结论是不适合我们,我没仔细研究

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/197719.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Vue3中使用Element-Plus分页(Pagination )组件

开发过程中数据展示会经常使用到&#xff0c;同时分页功能也会添加到页面中。 记&#xff1a;在Vue3中使用Element-Plus分页组件与表格数据实现分页交互。 开始实现 引入表格和分页组件的H5标签。 <strong>Element-Plus分页组件使用</strong> <div><el-t…

OSCP系列靶场-Esay-DC-1

目录 总结 准备工作 信息收集-端口扫描 目标开放端口收集 目标端口对应服务探测 信息收集-端口测试 22-SSH端口的信息收集 22-SSH端口版本信息与MSF利用(pass) 22-SSH手动登录尝试(失败) 22-SSH弱口令爆破(爆破着玩) 80-HTTP端口的信息收集 信息收集-网站指纹 漏洞…

目标检测 Faster RCNN全面解读复现

Faster RCNN 解读 经过R-CNN和Fast RCNN的积淀&#xff0c;Ross B. Girshick在2016年提出了新的Faster RCNN&#xff0c;在结构上&#xff0c;Faster RCNN已经将特征抽取(feature extraction)&#xff0c;proposal提取&#xff0c;bounding box regression(rect refine)&…

DataBinding原理

1、MainActivity首先使用DataBindingUtil.setContentView设置布局文件activity_main.xml。 2、随后&#xff0c;经过一系列函数调用&#xff0c;ActivityMainBindingImpl对象最终会实例化&#xff0c;并与activity_main.xml进行绑定。 3、实例化后的ActivityMainBindingImpl对象…

动画师如何选择全身动捕设备制作动画?

随着行业的不断发展&#xff0c;全身动捕设备在动画制作行业的应用已十分普遍。全身动捕设备分为光学动捕设备和惯性动捕设备&#xff0c;动画师该如何选择全身动捕设备制作动画&#xff1f; 与光学动捕设备相比&#xff0c;惯性动捕设备对场地和空间的限制更小&#xff0c;不…

重视日常消防巡检有必要,智能巡检系统来帮忙

近日,山西吕梁市永聚煤矿一办公楼发生火灾&#xff0c;造成重大人员伤亡&#xff0c;事故造成26人死亡、38人受伤。 是的&#xff0c;你没看错&#xff0c;煤矿公司、办公楼火灾、重大伤亡。第一反应&#xff0c;煤矿即使出事故也多为作业事故&#xff0c;居然还能在日常消防安…

【dc-dc】世微 电动车摩托车灯 5-80V 1.2A 一切二降压恒流驱动器AP2915

产品描述 AP2915 是一款可以一路灯串切换两路灯串的降压恒流驱动器,高效率、外围简单、内置功率管&#xff0c;适用于5-80V 输入的高精度降压 LED 恒流驱动芯片。内置功率管输出最大功率可达 12W&#xff0c;最大电流 1.2A。AP2915 一路灯亮切换两路灯亮&#xff0c;其中一路灯…

《洛谷深入浅出基础篇》 图的基本应用

什么是图&#xff1f; 我们在生活中学习中能看见很多图&#xff0c;地图&#xff0c;路线图&#xff0c;思维导图等等&#xff0c;它们都有一个特点&#xff0c; 你从中任找一个点&#xff0c;你可以找到&#xff0c;从这个点出发&#xff0c;能够到达什么地方&#xff0c;也…

9.docker镜像Tag为none的原因

1.现象 使用docker images命令查看镜像列表&#xff0c;会发现存在许多标签为none的镜像&#xff1a; 2. 原因 docker镜像标签为none的原因如下&#xff1a; &#xff08;1&#xff09;构建或重新拉取同名同Tag的新镜像&#xff1a;构建或重新拉取同名同Tag的新镜像后&…

斐波那契数列,剑指offer,力扣

目录 题目地址&#xff1a; 我们直接看题解吧&#xff1a; 解题方法&#xff1a; 难度分析&#xff1a; 审题目事例提示&#xff1a; 解题思路&#xff08;动态规划&#xff09;&#xff1a; 代码实现&#xff1a; 补充说明&#xff1a; 代码&#xff08;优化&#xff09;&…

如何从零开始制作一本企业宣传画册?

最近公司领导要求为公司制作一本企业宣传画册&#xff0c;用来展示我们的产品和服务&#xff0c;增加品牌影响力。可是&#xff0c;像我这种零基础的小白&#xff0c;完全不知道如何制作啊&#xff1f;对此我感到很焦虑&#xff0c;怕做不好影响公司形象&#xff0c;也怕耽误时…