用java代码重构php之sha256密码加密


字符串在底层无论是二进制还是十六进制都是一样的

php源码

 public function encodePassword($raw, $salt)
 {
     if ($this->isPasswordTooLong($raw)) {
         throw new BadCredentialsException('Invalid password.');
     }
 ?
     if (!in_array($this->algorithm, hash_algos(), true)) {
         throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
     }
     //合并明文密码和盐
     $salted = $this->mergePasswordAndSalt($raw, $salt);
     //使用sha256加密算法,将传入的字符串加密,返回原始的二进制数据
     $digest = hash($this->algorithm, $salted, true);
 ?
     // "stretch" hash  迭代加密 iterations=5000,algorithm=sha256
     for ($i = 1; $i < $this->iterations; ++$i) {
         $digest = hash($this->algorithm, $digest.$salted, true);
     }
     //使用base64加密
     return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest);
 }
php的hash()函数

https://www.php.net/manual/zh/function.hash.php

 hash(string $algo, string $data, bool $raw_output = false): string
  1. 参数 algo 要使用的哈希算法,例如:"md5","sha256","haval160,4" 等。 在 hash_algos() 中查看支持的算法。

    data 要进行哈希运算的消息。

    raw_output 设置为 true 输出原始二进制数据, 设置为 false 输出小写 16 进制字符串。

  2. 返回值 如果 raw_output 设置为 true, 则返回原始二进制数据(字节数组)表示的信息摘要, 否则返回 16 进制小写字符串格式表示的信息摘要。

java代码

参考资料: MessageDigest的api-

需要导入的依赖,可能还需要spring-security的依赖

         <dependency>
             <groupId>org.bouncycastlegroupId>
             <artifactId>bcprov-jdk15onartifactId>
             <version>1.64version>
         dependency>
         <dependency>
             <groupId>cn.hutoolgroupId>
             <artifactId>hutool-allartifactId>
             <version>5.4.3version>
         dependency>
         <dependency>
             <groupId>commons-langgroupId>
             <artifactId>commons-langartifactId>
             <version>2.6version>
         dependency>
 package com.saiyou.web.controller;
 ?
 import cn.hutool.core.codec.Base64;
 import org.apache.commons.lang.ArrayUtils;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import java.io.UnsupportedEncodingException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 ?
 //技术点 :sha256加密工具
 public class Sha256Utils {
 ?
     //使用sha256加密明文密码
     public static String encoder(String passwordAndSalt) throws NoSuchAlgorithmException, UnsupportedEncodingException {
 ?
         String salted = passwordAndSalt;
         MessageDigest digester = MessageDigest.getInstance("SHA-256", new BouncyCastleProvider());
         byte[] hash = digester.digest(salted.getBytes());
         for (int i = 1; i < 5000; i++) {
             hash = digester.digest(ArrayUtils.addAll(hash, salted.getBytes()));
         }
         String password = Base64.encode(hash);
         return password;
     }
     
 ?
     public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {
         //明文密码和盐拼接的字符串
         String salted = "123456" + "{b7z8wmjex6gwk044o8sc004gc4048sk}";
         //数据库密码
         String dbPassword = "9Sb1AJbe+JVP/xpgOg659dDEY9Bsp1S9az45WZKzdsw=";
         //加密
         String password = Sha256Utils.encoder(salted);
         System.out.println(dbPassword.equals(password));//true
 ?
     }
 }
MessageDigest的api
java.security.MessageDigest类用于为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。简单点说就是用于生成散列码。

 getInstance(String algorithm, Provider provider) 
           生成实现指定提供程序提供的指定算法的 MessageDigest 对象,假设该算法可从指定的提供程序得到的话。
 digest(byte[] input) 
           使用指定的字节数组对摘要进行最后更新,然后完毕摘要计算。
BouncyCastleProvider轻量级的密码包,加密不要随便new会有内存泄漏,考虑弄成单例的;

相关