做美容仪器的网站,网站开发 模块化,工信部网站备案变更,什么网站可以做医疗设备的文章目录 项目地址#xff1a; 一、md5 与 先进的哈希算法的区别1.1. 安全性问题1.2. 设计目的1.3. 功能特性1.4. 适用性1.5. 总结 二、数据传输安全和数据加密实现#xff1a;2.1 生成证书#xff1a;2.2、在springboot中进行集成2.2.1 配置证书#xff1a;2.2.2. 强制使用… 文章目录 项目地址 一、md5 与 先进的哈希算法的区别1.1. 安全性问题1.2. 设计目的1.3. 功能特性1.4. 适用性1.5. 总结 二、数据传输安全和数据加密实现2.1 生成证书2.2、在springboot中进行集成2.2.1 配置证书2.2.2. 强制使用 HTTPS2.2.2.1 实现过程 2.2.3 使用bcrypt 进行密码加密2.2.3.1实现过程2.2.3.2 BCryptPasswordEncoder 的实现逻辑 三、权限控制3.1、菜单权限控制3.1.1具体步骤 3.2、按钮权限3.2.1 具体步骤3.2.2 流程图 别的在Springboot中使用Argon2进行密码加密 不依靠 SpringScurity1. 添加 Argon2 库的依赖2. 散列密码3. 验证密码4. 使用例子验证逻辑小结 项目地址
https://github.com/yszhdhy/ItemSet/tree/master/java/secureAndSpringScurity
项目结构
一、md5 与 先进的哈希算法的区别
先进的hash算法有 bcrypt、PBKDF2 或 Argon2
实际上使用 bcrypt、PBKDF2 或 Argon2 进行密码散列与使用 MD5 有着显著的区别主要在于安全性和适用性。虽然 MD5 曾广泛用于密码散列但它现在被认为是不安全的选择主要原因如下
1.1. 安全性问题
快速计算MD5 设计用于快速计算文件或数据的散列值这使得它在抵抗暴力破解攻击方面表现不佳。攻击者可以使用现代的硬件在极短的时间内尝试数十亿个密码组合。碰撞弱点MD5 已经被证明存在碰撞弱点即可以找到两个不同的输入产生相同的输出。这种特性使其不适合进行密码存储或任何需要高安全性的场景。
1.2. 设计目的
MD5最初设计为快速计算数据的散列用于检查文件完整性而非密码存储。bcrypt/PBKDF2/Argon2特别为密码存储设计包括对抗散列速度过快的攻击手段如密钥拉伸和盐值使用这些都是为了增加密码破解的难度。
1.3. 功能特性
密钥拉伸bcrypt、PBKDF2 和 Argon2 实现了密钥拉伸功能可以通过增加计算的时间和资源需求来有效抵抗暴力破解攻击。盐值使用这些算法在散列密码时使用盐值可以有效防止彩虹表攻击即使是两个相同的密码在加了不同的盐之后产生的散列值也会不同。
1.4. 适用性
广泛适用虽然你提到“大多数项目都是使用 MD5 进行加密”但实际上在安全性意识提高和数据泄露事件频发的当下许多现代应用和安全标准推荐使用 bcrypt、PBKDF2 或 Argon2 作为密码存储的首选方法。
1.5. 总结
如果你在设计一个需要存储用户密码的系统强烈建议使用 bcrypt、PBKDF2 或 Argon2 而不是 MD5。这些现代算法提供了更高级别的安全保障可以帮助你的系统抵御当前的威胁如暴力破解和彩虹表攻击。选择正确的密码存储策略是保护用户数据安全的关键一步。
二、数据传输安全和数据加密实现
2.1 生成证书 执行命令 keytool -genkeypair -alias mydomain -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore mykeystore.p12 -validity 3650 -storepass yourpassword命令详解 keytool: 这是 Java 提供的一个用于管理密钥和证书的命令行工具。-genkeypair: 这个参数告诉 keytool 生成一个密钥对包括一个公钥和一个相应的私钥。-alias mydomain: 这个参数指定了密钥对的别名。在之后的操作中可以使用这个别名来引用这个密钥对。-keyalg RSA: 这个参数指定了要使用的密钥算法。在这种情况下RSA 算法被选用。-keysize 2048: 这个参数指定了生成的密钥的位长度。在这个例子中密钥的长度为 2048 位。-storetype PKCS12: 这个参数指定了密钥库的类型。在这里选择了 PKCS#12 格式。-keystore mykeystore.p12: 这个参数指定了要生成的密钥库的文件名。在这个例子中生成的密钥库将被命名为 mykeystore.p12。-validity 3650: 这个参数指定了生成的证书的有效期限。在这里证书的有效期限被设置为 3650 天大约 10 年。-storepass yourpassword: 这个参数指定了密钥库的密码。在这个例子中密码被设置为 yourpassword。请确保将 yourpassword 替换为你自己的密码。
2.2、在springboot中进行集成
2.2.1 配置证书 将生成的证书放置在resource目录下 配置yaml spring:application:name: demoserver:ssl:key-store: src/main/resources/mykeystore.p12key-store-password: xu123456keyStoreType: PKCS12 # 存储加密信息的标准文件格式keyAlias: mydomain # 别名用于从密钥库中引用具体的密钥port: 8840启动项目并使用cmd 进行测试
总结
完成以上操作后我们的所有的请求 都需要使用https进行访问。
2.2.2. 强制使用 HTTPS
2.2.2.1 实现过程 首先导入本次项目所需要的所有依赖 dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.30/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-configuration-processor/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.4.1/version/dependencydependencygroupIdcom.github.xiaoymin/groupIdartifactIdknife4j-spring-boot-starter/artifactIdversion3.0.3/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId/dependencydependencygroupIdorg.springframework.security/groupIdartifactIdspring-security-config/artifactId/dependencydependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion2.0.21/version/dependency/dependencies配置yaml文件 spring:application:name: demodatasource:password: 123456driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/ceshi?useUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/Shanghaiusername: rootmvc:format:date: yyyy-MM-dddate-time: yyyy-MM-dd HH:mm:ssserver:port: 8840 # HTTP端口ssl:enabled: trueport: 8843 # HTTPS端口key-store: src/main/resources/mykeystore.p12key-store-password: xu123456keyStoreType: PKCS12keyAlias: mydomain搭建security配置文件 WebSecurityConfig 考虑在你的应用中强制使用 HTTPS以避免数据通过不安全的 HTTP 发送。在 Spring Security 中可以通过配置安全性策略来实现 EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {Overrideprotected void configure(HttpSecurity http) throws Exception {http.requiresChannel() //指定了需要使用的通道类型.anyRequest() // 指定了所有的请求.requiresSecure(); // 指定了需要使用安全的HTTPS通道}
}这样配置后所有请求都会被重定向到 HTTPS (即使用户输入http)。
2.2.3 使用bcrypt 进行密码加密
2.2.3.1实现过程 创建密码加密配置文件 SecurityConfig 在添加用户业务中可以使用此 BCryptPasswordEncoder.encode() 方法进行加密用户密码并存储在数据库中 package com.example.demo.config.passwordEncoder;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;/*** author CaptureOrNew* description //进行密码加密配置* date 19:29:12 2024/4/19* return null**/
Configuration
public class SecurityConfig {// 进行编码配置 创建一个BCryptPasswordEncoder的实例Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}// 配置其他安全措施...
} 创建一个密码编辑器 package com.example.demo.security.custom;import com.example.demo.config.passwordEncoder.SecurityConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;/*** author CaptureOrNew* description //创建一个bcrypt 加密器* date 19:28:21 2024/4/19* Param* return null**/
Component
public class CustomBcryptPasswordEncoder implements PasswordEncoder {AutowiredSecurityConfig securityConfig;// 进行密码加密操作public String encode(CharSequence rawPassword) {return securityConfig.passwordEncoder().encode(rawPassword.toString());}// 进行密码比对public boolean matches(CharSequence rawPassword, String encodedPassword) {// security 会自动进行密码的比对return securityConfig.passwordEncoder().matches(rawPassword, encodedPassword);}
} 创建一个 UserDetailsService 接口 以及下面的实现类进行 数据库用户查询和一些鉴权判断 package com.example.demo.security.custom;import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;Component
public interface UserDetailsService extends org.springframework.security.core.userdetails.UserDetailsService {/*** 根据用户名获取用户对象获取不到直接抛异常*/OverrideUserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}实现类 package com.example.demo.service.impl;import com.example.demo.model.model.SysUser;
import com.example.demo.security.custom.CustomUser;
import com.example.demo.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.List;Service
public class UserDetailsServiceImpl implements UserDetailsService {Autowiredprivate SysUserService sysUserService;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//根据用户名进行查询SysUser sysUser sysUserService.getUserByUserName(username);if(null sysUser) {throw new UsernameNotFoundException(用户名不存在);}if(sysUser.getStatus().intValue() 0) {throw new RuntimeException(账号已停用);}ListSimpleGrantedAuthority authList new ArrayList();return new CustomUser(sysUser, authList);}
}
2.2.3.2 BCryptPasswordEncoder 的实现逻辑
加密 (encode) 过程 用户提供一个明文密码。生成一个随机盐值通常是每次加密时生成的。使用明文密码和生成的盐值通过 BCrypt 算法进行多轮散列处理。将盐值和散列结果合并成一个字符串通常在字符串中包含盐值、散列值和用于 BCrypt 的成本参数。返回这个合并后的字符串作为最终的存储散列。 验证 (matches) 过程 用户尝试登录时提供一个明文密码。取出数据库中存储的散列密码这个散列包含了用于该特定密码的盐值。使用存储的盐值和用户提供的明文密码再次执行相同的 BCrypt 散列过程。比较新生成的散列结果与存储的散列值是否一致。如果两者一致说明密码匹配用户验证成功如果不一致则验证失败。 流程图 -----------------------| 用户注册 |-----------------------| 输入明文密码 |-----------------------↓-----------------------| 生成随机盐值 |-----------------------↓-----------------------| 使用 BCrypt 加密 || (密码 盐值) |-----------------------↓-----------------------| 存储散列密码到数据库 |-----------------------↓-----------------------| 用户登录 |-----------------------| 输入明文密码 |-----------------------↓-----------------------| 读取存储的散列密码 || (包含盐值) |-----------------------↓-----------------------| 使用读取的盐值重新 || 加密输入的明文密码 |-----------------------↓-----------------------| 比较两个散列值是否相同|-----------------------↓-----------------------| 相同: 验证成功 || 不同: 验证失败 |-----------------------
三、权限控制
以下操作基于RBAC 角色访问控制 权限管理模型
给用户分配角色 —— 给角色分配权限可对项目进行的操作
3.1、菜单权限控制
在用户每次登录系统获取信息时后端通过用户名和密码在数据库中进行查找此用户如果查询到此用户就根据用户所处的角色及角色所能操作的菜单查询出来将查询到的菜单组装为前端的路由形式进行返回给前端。这样就实现了根据用户的身份角色不同客户端就会展示相应的菜单等。
3.1.1具体步骤
用户登录后紧接着获取菜单信息从请求头获取用户信息即token从数据在token中解析出登录用户的ID根据ID查询用户信息根据用户信息查询用户可操作的菜单组装菜单并返回前端通过动态路由的形式进行插入到项目中。
3.2、按钮权限
根据用户可以操作的按钮进行来控制那些后端方法也就是接口是可以被用户所访问的CURD。
3.2.1 具体步骤 前端中会根据用户登录后获取信息的接口获取到按钮权限。在前端中使用获取到的按钮权限信息对相应的按钮进行禁用或其他操作 我们后端中 security 配置类 TokenAuthenticationFilter 中进行配置获取用户按钮权限的操作并存入到security 身上 Overrideprotected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain chain) throws ServletException, IOException {//如果是登录接口直接放行if (/admin/system/index/login.equals(request.getRequestURI())) {chain.doFilter(request, response);return;}// 获取校验信息UsernamePasswordAuthenticationToken authentication getAuthentication(request);if (null ! authentication) {SecurityContextHolder.getContext().setAuthentication(authentication);chain.doFilter(request, response);} else {ResponseUtil.out(response, Result.build(null, ResultCodeEnum.LOGIN_ERROR));}}private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {//请求头是否有tokenString username request.getHeader(token);if (!StringUtils.isEmpty(username)) {String authListString request.getHeader(authorities);if (!StringUtils.isEmpty(authListString)) {System.out.println(authListString);String ccc authListString;//把redis获取字符串权限数据转换要求集合类型 ListSimpleGrantedAuthorityListMap maplist JSON.parseArray(ccc, Map.class);System.out.println(maplist);ListSimpleGrantedAuthority authList new ArrayList();for (Map map : maplist) {String authority (String) map.get(authority);authList.add(new SimpleGrantedAuthority(authority));}return new UsernamePasswordAuthenticationToken(username, null, authList);} else {return new UsernamePasswordAuthenticationToken(username, null, new ArrayList());}}return null;}这样我们就可以直接调用security中的一个注解进行 校验 PreAuthorize(hasAuthority(bnt.sysUser.list)) /*** author CaptureOrNew* description //查询用户列表* date 09:46:22 2024/4/20* PreAuthorize 标注在方法上表示访问方法的用户需要有对应的权限* return com.example.demo.result.Resultjava.util.List com.example.demo.model.model.SysUser**/PreAuthorize(hasAuthority(bnt.sysUser.list))GetMapping(getUserList)public ResultListSysUser getUserList() {ListSysUser list sysUserService.list();return list ! null ? Result.ok(list) : Result.build(null, LOGIN_ERROR);}测试验证数据 这里我们是将权限放在header中了 没有使用redis const axios require(axios);let config {method: get,maxBodyLength: Infinity,url: https://localhost:8840/admin/getUserList,headers: { token: admin, authorities: [{authority:bnt.sysUser.remove},{authority:bnt.sysUser.add},{authority:bnt.sysUser.update}]}
};axios.request(config)
.then((response) {console.log(JSON.stringify(response.data));
})
.catch((error) {console.log(error);
});
3.2.2 流程图 用户登录 用户添加
别的
在Springboot中使用Argon2进行密码加密 不依靠 SpringScurity
1. 添加 Argon2 库的依赖
如果你的项目中使用 Java你可以添加如下依赖例如使用 argon2-jvm 库
xmlCopy code!-- Maven 依赖 --
dependencygroupIdde.mkammerer/groupIdartifactIdargon2-jvm/artifactIdversion2.8/version
/dependency2. 散列密码
创建一个服务类实现密码的散列功能。这里是一个简单的例子展示如何使用 Argon2 进行密码散列
javaCopy codeimport de.mkammerer.argon2.Argon2;
import de.mkammerer.argon2.Argon2Factory;public class PasswordService {private Argon2 argon2 Argon2Factory.create();public String hashPassword(String password) {// 参数解释: 迭代次数, 内存使用量, 并行度表示算法同时使用的线程数或CPU核心数return argon2.hash(2, 65536, 1, password.toCharArray());}
}3. 验证密码
验证过程中你需要比较用户输入的密码与数据库中存储的散列值是否匹配。这可以通过 Argon2 的验证功能来实现
javaCopy codepublic boolean verifyPassword(String inputPassword, String storedHash) {return argon2.verify(storedHash, inputPassword.toCharArray());
}4. 使用例子
在你的业务逻辑中可以使用这个服务来处理用户的密码。例如在用户注册时散列密码用户登录时验证密码
javaCopy codepublic class UserService {private PasswordService passwordService new PasswordService();// 用户注册public void registerUser(String username, String password) {String hashedPassword passwordService.hashPassword(password);// 存储 username 和 hashedPassword 到数据库}// 用户登录public boolean loginUser(String username, String inputPassword) {// 从数据库获取存储的散列密码String storedHash ...;return passwordService.verifyPassword(inputPassword, storedHash);}
}验证逻辑
Argon2 的验证逻辑内部会处理与散列值相关的盐值和参数配置所以你不需要手动处理盐值。当你调用 argon2.verify 方法时它会解析存储的散列值自动提取盐值和散列参数然后使用这些信息来验证输入密码。
小结
使用 Argon2 手动处理密码散列和验证确实比直接使用 Spring Security 稍复杂一些但这提供了更高的灵活性和控制适合不使用 Spring Security 的项目。确保在实际部署中正确管理密码相关的安全细节如使用安全的参数配置和及时更新依赖库。 文章转载自: http://www.morning.zhnyj.cn.gov.cn.zhnyj.cn http://www.morning.qcwck.cn.gov.cn.qcwck.cn http://www.morning.hgcz.cn.gov.cn.hgcz.cn http://www.morning.gwqq.cn.gov.cn.gwqq.cn http://www.morning.txrq.cn.gov.cn.txrq.cn http://www.morning.rjrnx.cn.gov.cn.rjrnx.cn http://www.morning.lzrpy.cn.gov.cn.lzrpy.cn http://www.morning.ssjee.cn.gov.cn.ssjee.cn http://www.morning.kzpxc.cn.gov.cn.kzpxc.cn http://www.morning.smwlr.cn.gov.cn.smwlr.cn http://www.morning.gywfp.cn.gov.cn.gywfp.cn http://www.morning.bwgrd.cn.gov.cn.bwgrd.cn http://www.morning.njddz.cn.gov.cn.njddz.cn http://www.morning.xnbd.cn.gov.cn.xnbd.cn http://www.morning.wjdgx.cn.gov.cn.wjdgx.cn http://www.morning.tmfhx.cn.gov.cn.tmfhx.cn http://www.morning.mrbmc.cn.gov.cn.mrbmc.cn http://www.morning.pjxlg.cn.gov.cn.pjxlg.cn http://www.morning.qnbzs.cn.gov.cn.qnbzs.cn http://www.morning.wcgcm.cn.gov.cn.wcgcm.cn http://www.morning.nccqs.cn.gov.cn.nccqs.cn http://www.morning.ytrbq.cn.gov.cn.ytrbq.cn http://www.morning.mhmdx.cn.gov.cn.mhmdx.cn http://www.morning.ppdr.cn.gov.cn.ppdr.cn http://www.morning.dbylp.cn.gov.cn.dbylp.cn http://www.morning.yxdrf.cn.gov.cn.yxdrf.cn http://www.morning.fyzsq.cn.gov.cn.fyzsq.cn http://www.morning.qqnh.cn.gov.cn.qqnh.cn http://www.morning.rqkzh.cn.gov.cn.rqkzh.cn http://www.morning.zlsmx.cn.gov.cn.zlsmx.cn http://www.morning.pswzc.cn.gov.cn.pswzc.cn http://www.morning.jcjgh.cn.gov.cn.jcjgh.cn http://www.morning.frcxx.cn.gov.cn.frcxx.cn http://www.morning.lfgql.cn.gov.cn.lfgql.cn http://www.morning.wjtxt.cn.gov.cn.wjtxt.cn http://www.morning.hsjrk.cn.gov.cn.hsjrk.cn http://www.morning.china-cj.com.gov.cn.china-cj.com http://www.morning.rwbx.cn.gov.cn.rwbx.cn http://www.morning.hyfrd.cn.gov.cn.hyfrd.cn http://www.morning.wlxfj.cn.gov.cn.wlxfj.cn http://www.morning.tplht.cn.gov.cn.tplht.cn http://www.morning.ypcbm.cn.gov.cn.ypcbm.cn http://www.morning.lywpd.cn.gov.cn.lywpd.cn http://www.morning.rrrrsr.com.gov.cn.rrrrsr.com http://www.morning.ybnzn.cn.gov.cn.ybnzn.cn http://www.morning.fpxms.cn.gov.cn.fpxms.cn http://www.morning.mlcnh.cn.gov.cn.mlcnh.cn http://www.morning.bwygy.cn.gov.cn.bwygy.cn http://www.morning.zxybw.cn.gov.cn.zxybw.cn http://www.morning.rhzzf.cn.gov.cn.rhzzf.cn http://www.morning.wyzby.cn.gov.cn.wyzby.cn http://www.morning.dmtbs.cn.gov.cn.dmtbs.cn http://www.morning.zgpgl.cn.gov.cn.zgpgl.cn http://www.morning.xbmwh.cn.gov.cn.xbmwh.cn http://www.morning.gtbjc.cn.gov.cn.gtbjc.cn http://www.morning.smggx.cn.gov.cn.smggx.cn http://www.morning.cpctr.cn.gov.cn.cpctr.cn http://www.morning.ktqtf.cn.gov.cn.ktqtf.cn http://www.morning.smszt.com.gov.cn.smszt.com http://www.morning.fyglg.cn.gov.cn.fyglg.cn http://www.morning.kyjpg.cn.gov.cn.kyjpg.cn http://www.morning.hqsnt.cn.gov.cn.hqsnt.cn http://www.morning.fxpyt.cn.gov.cn.fxpyt.cn http://www.morning.fgrkc.cn.gov.cn.fgrkc.cn http://www.morning.htmhl.cn.gov.cn.htmhl.cn http://www.morning.jqhrk.cn.gov.cn.jqhrk.cn http://www.morning.phjyb.cn.gov.cn.phjyb.cn http://www.morning.rwmft.cn.gov.cn.rwmft.cn http://www.morning.dkqr.cn.gov.cn.dkqr.cn http://www.morning.jlboyuan.cn.gov.cn.jlboyuan.cn http://www.morning.jglqn.cn.gov.cn.jglqn.cn http://www.morning.pngfx.cn.gov.cn.pngfx.cn http://www.morning.mzhjx.cn.gov.cn.mzhjx.cn http://www.morning.xyhql.cn.gov.cn.xyhql.cn http://www.morning.jcfdk.cn.gov.cn.jcfdk.cn http://www.morning.ltzkk.cn.gov.cn.ltzkk.cn http://www.morning.kwqcy.cn.gov.cn.kwqcy.cn http://www.morning.qywfw.cn.gov.cn.qywfw.cn http://www.morning.lbgsh.cn.gov.cn.lbgsh.cn http://www.morning.gczzm.cn.gov.cn.gczzm.cn