字符串在底层无论是二进制还是十六进制都是一样的
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
参数 algo 要使用的哈希算法,例如:"md5","sha256","haval160,4" 等。 在 hash_algos() 中查看支持的算法。
data 要进行哈希运算的消息。
raw_output 设置为 true 输出原始二进制数据, 设置为 false 输出小写 16 进制字符串。
返回值 如果 raw_output 设置为 true, 则返回原始二进制数据
(字节数组)
表示的信息摘要, 否则返回 16 进制小写字符串
格式表示的信息摘要。
java代码
参考资料: MessageDigest的api-https://www.cnblogs.com/mengfanrong/p/3896447.html
需要导入的依赖,可能还需要spring-security的依赖
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.64</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.4.3</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </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会有内存泄漏,考虑弄成单例的;