BCrypt 密码加密

1 介绍

任何应用考虑到安全,绝不能明文的方式保存密码。密码应该通过哈希算法进行加密。有很多标准的算法比 SHA 或者 MD5,结合 salt (盐)是一个不错的选择。 Spring Security 提供了 BCryptPasswordEncoder 类,实现 Spring 的 PasswordEncoder 接口使用 BCrypt 强哈希方法来加密密码。
BCrypt 强哈希方法每次加密的结果都不一样。

2 准备工作

2.1 引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

2.2 添加配置类

/**
 * 安全配置类
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/**").permitAll()
                .anyRequest().authenticated()
                .and().csrf().disable();
    }
}

说明:

  • @Configuration:用于定义配置类的注解。
  • @EnableWebSecurity:是 Spring Security 用于启用 Web 安全的注解。
  • authorizeRequests():所有 security 全注解配置实现的开端,表示开始说明需要的权限。需要的权限分为两个部分:1.拦截的路径;2.访问该路径需要的权限。
  • antMatchers():表示拦截什么路径。
  • permitAll():表示任何权限到可以访问,直接放行所有。
  • anyRequest():任何的请求。
  • authenticated():认证之后才能访问。
  • .and().csrf().disable():固定写法,表示使 csrf 拦截失效。

2.3 把 BCryptPasswordEncoder 类注入容器

@SpringBootApplication
public class UserApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }

    @Bean
    public IdWorker idWorker() {
        return new IdWorker(1, 1);
    }

    @Bean
    public BCryptPasswordEncoder bcryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

3 加密

3.1 Service 层

这里我在 service 层调用 BCryptPasswordEncoderpublic String encode(CharSequence rawPassword) 方法对前端传过来的密码进行加密。

@Service
public class AdminService {
    @Autowired
    AdminDao adminDao;

    @Autowired
    IdWorker idWorker;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    public void addAdmin(Admin admin) {
        admin.setId(idWorker.nextId() + "");
        admin.setPassword(bCryptPasswordEncoder.encode(admin.getPassword()));
        adminDao.save(admin);
    }
}

3.2 dao 层

dao 层用的 Spring JPA 和数据库交互。

public interface AdminDao extends JpaRepository<Admin, String>, JpaSpecificationExecutor<Admin> {
}

3.3 controller 层

@RequestMapping(value = "/admin")
@RestController
@CrossOrigin
public class AdminController {

    @Autowired
    AdminService adminService;

    @PostMapping
    public Result addAdmin(@RequestBody Admin admin) {
        adminService.addAdmin(admin);
        return new Result(StatusCode.OK, true, "增加管理员成功");
    }
}

3.4 测试

在这里插入图片描述
前端的密码是 123,经过 BCrypt 加密之后,数据库中保存的内容就是一串乱码了,加密成功。

4 密码校验

4.1 AdminDao 增加方法定义

用过登录名从数据库中获取管理员信息。

public interface AdminDao extends JpaRepository<Admin, String>, JpaSpecificationExecutor<Admin> {
    Admin findByLoginname(String loginname);
}

4.2 AdminService 增加方法

Service 层添加一个 Admin login(Admin admin) 方法用于登录。
注意:public boolean matches(CharSequence rawPassword, String encodedPassword) 方法中,第一位填写 “生密码” 即手动输入的密码,第二位填写 “加密之后的密码” 即数据库中保存的密码。

public Admin login(Admin admin) {
    Admin adminFromSQL = adminDao.findByLoginname(admin.getLoginname());
    if (adminFromSQL != null && bCryptPasswordEncoder.matches(admin.getPassword(), adminFromSQL.getPassword())) {
    	return adminFromSQL;
    }
    return null;
}

4.3 AdminController 增加方法

@PostMapping(value = "/login")
public Result login(@RequestBody Admin admin) {
	Admin adminLogin = adminService.login(admin);
	if (adminLogin == null) {
		return new Result(StatusCode.ERROR, false, "登录失败");
	}
	return new Result(StatusCode.OK, true, "登录成功");
}

4.4 测试

我们的密码是 123,输入 111 时,返回登录失败。
在这里插入图片描述
在这里插入图片描述

非常抱歉,我之前提供的代码存在错误。在 PyTorch 中,并没有直接提供离散余弦变换(DCT)的函数。对于 DCT 的实现,你可以使用 `torch.rfft` 函数结合 DCT 系数矩阵来进行计算。 下面是一个修正后的示例代码: ```python import torch import torch.nn as nn import torch.optim as optim # 定义离散余弦变换(DCT)系数矩阵 dct_matrix = torch.zeros(256, 256) for i in range(256): for j in range(256): dct_matrix[i, j] = torch.cos((2 * i + 1) * j * 3.14159 / (2 * 256)) # 定义 OMP 算法 def omp(A, y, k): m, n = A.shape x = torch.zeros(n, 1) residual = y.clone() support = [] for _ in range(k): projections = torch.abs(A.t().matmul(residual)) index = torch.argmax(projections) support.append(index) AtA_inv = torch.linalg.inv(A[:, support].t().matmul(A[:, support])) x_new = AtA_inv.matmul(A[:, support].t()).matmul(y) residual = y - A[:, support].matmul(x_new) x[support] = x_new return x # 加载原始图像 image = torch.randn(256, 256) # 压缩感知成像 measurement_matrix = torch.fft.fft(torch.eye(256), dim=0).real compressed = measurement_matrix.matmul(image.flatten().unsqueeze(1)) # 使用 OMP 进行重构 reconstructed = omp(dct_matrix, compressed, k=100) # 计算重构误差 mse = nn.MSELoss() reconstruction_error = mse(image, reconstructed.reshape(image.shape)) print("重构误差:", reconstruction_error.item()) ``` 在这个示例中,我们手动定义了 DCT 系数矩阵 `dct_matrix`,然后使用 `torch.fft.fft` 函数计算测量矩阵,并进行实部提取。接下来的步骤与之前的示例相同。 请注意,这只是一个示例,用于演示如何使用自定义的 DCT 系数矩阵进行压缩感知成像。在实际应用中,你可能需要根据具体的需求进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值