简介:
先介绍下java中PasswordEncoder接口的实现类 MessageDigestPasswordEncoder 能够实现使用随机盐值通过摘要算法生成每次都不一样的不可逆的加密字符串,并且通过matches都能正确匹配
由于最近重写java代码还要兼容其密码信息 下面是我使用go语言重写java语言的加密实现,已经经过10亿次随机全类型字符串的测试,有什么问题欢迎指正。
java
以下是自己对java代码MessageDigestPasswordEncoder 类中的encode和 matches的简单解读,都在注释中
encode:
* Encodes the rawPass using a MessageDigest. If a salt is specified it will be merged
* with the password before encoding.
*
* @param rawPassword The plain text password
* @return Hex string of password digest (or base64 encoded string if
* encodeHashAsBase64 is enabled.
*/
public String encode(CharSequence rawPassword) {
//随机生成字符串,再转化成base64字符串拼接出salf
String salt = PREFIX + this.saltGenerator.generateKey() + SUFFIX;
//调用digest函数,
//1.内部实现明文密码与salt的字符拼接
//2.将字符串转成byte数组
//3.使用算法加密并返回base64字符串
//4.随机盐(salt)与返回的加密base64拼接返回作为加密后的字符串
return digest(salt, rawPassword);
}
matches:
/**
* Takes a previously encoded password and compares it with a rawpassword after mixing
* in the salt and encoding that value
*
* @param rawPassword plain text password
* @param encodedPassword previously encoded password
* @return true or false
*/
public boolean matches(CharSequence rawPassword, String encodedPassword) {
//拆分字符串 拆出{}中的内容
String salt = extractSalt(encodedPassword);
//调用digest函数,
//1.内部实现明文密码与salt的字符拼接
//2.将字符串转成byte数组
//3.使用算法加密并返回base64字符串
//4.随机盐(salt)与返回的加密base64拼接返回作为加密后的字符串
String rawPasswordEncoded = digest(salt, rawPassword);
//5.将密文与原密文比较 确认密码是否正确
return PasswordEncoderUtils.equals(encodedPassword.toString(), rawPasswordEncoded);
}
go
直接上代码
完全按照java的逻辑写的
package main
import (
"crypto/sha512"
"encoding/base64"
"encoding/hex"
"fmt"
"math/rand"
"strings"
"time"
)
const (
PREFIX = "{"
SUFFIX = "}"
keyLength = 32
base64Table = "123QRSTUabcdVWXYZHijKLAWDCABDstEFGuvwxyzGHIJklmnopqr234560178912"
)
func main() {
password := "wanglulu"
for i := 0; i <= 5; i++ {
//加密
encodedPassword := Encode(password)
fmt.Println("EncodedPassword:",encodedPassword)
//匹配
b := Matches(password, encodedPassword)
fmt.Println("Matche:",b)
}
}
func Matches(rawPassword, encodedPassword string) bool {
salt := extractSalt(encodedPassword)
rawPasswordEncoded := digest(salt, rawPassword)
if rawPasswordEncoded == encodedPassword {
return true
}
return false
}
func Encode(rawPassword string) string {
salf := fmt.Sprintf("%s%s%s", PREFIX, generateKey(), SUFFIX)
return digest(salf, rawPassword)
}
func generateKey() string {
randomString := getRandomString(keyLength)
var coder = base64.NewEncoding(base64Table)
base64EncodedKey := coder.EncodeToString([]byte(randomString))
return base64EncodedKey
}
func extractSalt(string2 string) string {
i := strings.Index(string2, "}")
salt := string2[0 : i+1]
return fmt.Sprintf("%s", salt)
}
func digest(salt, rawPassword string) string {
saltedPassword := fmt.Sprintf("%s%s", rawPassword, salt)
s_ob := sha512.New()
s_ob.Write([]byte(saltedPassword))
r := s_ob.Sum(nil)
encodedStr := hex.EncodeToString(r)
return fmt.Sprintf("%s%s", salt, encodedStr)
}
func getRandomString(l int) string {
bytes := []byte(base64Table)
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < l; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
return string(result)
}
网友评论