golang 解析 jasypt 加密

golang 解析 jasypt 加密,第1张

1. 说明

产品中的微服务开发使用了 beego框架和 springboot 框架,对于 springboot ,jasypt 提供了 starter 轻松实现数据库密码加解密功能。在参考了互联网相关代码后,手动实现了一版随机 salt 下的 go 解密 PBEWITHMD5ANDDES 算法。解决了在 go 项目中使用 jasypt 加密内容对数据库密码加密问题。

参考地址:https://github.com/pineda89/PBEWithMD5AndDES

2. springboot jasypt 加解密
// 加密
public String encrypt(String plaintext, String password, String algorithm, Integer iterations) {
     PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();

     SimpleStringPBEConfig config = new SimpleStringPBEConfig();
     config.setPassword(password);
     config.setAlgorithm(algorithm);
     config.setKeyObtentionIterations(iterations);
     config.setPoolSize("1");
     config.setProviderName("SunJCE");
     config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
     config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
     config.setStringOutputType("base64");

     encryptor.setConfig(config);

     return encryptor.encrypt(plaintext);
 }

// 解密
 public String decrypt(String cipherText, String password, String algorithm, Integer iterations) {
     PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();

     SimpleStringPBEConfig config = new SimpleStringPBEConfig();
     config.setPassword(password);
     config.setAlgorithm(algorithm);
     config.setKeyObtentionIterations(iterations);
     config.setPoolSize("1");
     config.setProviderName("SunJCE");
     config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
     config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
     config.setStringOutputType("base64");

     encryptor.setConfig(config);

     return encryptor.decrypt(cipherText);
 }

3. golang jasypt 解密
package utils

import (
	"crypto/cipher"
	"crypto/des"
	"crypto/md5"
	"encoding/base64"
	"strings"
)

const (
	trimBytes = "\x01\x02\x03\x04\x05\x06\x07\x08"

	defaultSaltSizeBytes = 8
	defaultIvSizeBytes   = 16
)

// jasypt 解码器
type JasyptDecoder struct {
	Enabled    bool   // 是否启用
	EncPrefix  string // 加密字段前缀内容
	EncSuffix  string // 加密字段后缀内容
	Algorithm  string // 算法名称
	Password   string // 加解密密码
	Iterations int    // hash 迭代次数
}

// jasypt 加解密支持
func (j *JasyptDecoder) Decrypt(cipherText string) (string, error) {
	if !j.Enabled {
		return cipherText, nil
	}

	prefixIndex := strings.Index(cipherText, j.EncPrefix)
	suffixIndex := strings.Index(cipherText, j.EncSuffix)
	if prefixIndex != 0 || suffixIndex != len(cipherText)-1 {
		return cipherText, nil
	}

	cipherText = strings.Replace(cipherText, j.EncPrefix, "", 1)
	cipherText = strings.Replace(cipherText, j.EncSuffix, "", 1)

	decodeString, err := base64.StdEncoding.DecodeString(cipherText)
	if err != nil {
		return "", err
	}

	salt := decodeString[:defaultSaltSizeBytes]
	msgBytes := decodeString[defaultIvSizeBytes:]

	dk, iv := getDerivedKey(j.Password, salt, j.Iterations)
	block, err := des.NewCipher(dk)
	if err != nil {
		return "", err
	}

	decrypter := cipher.NewCBCDecrypter(block, iv)
	decrypted := make([]byte, len(msgBytes))
	decrypter.CryptBlocks(decrypted, msgBytes)

	decryptedString := strings.TrimRight(string(decrypted), trimBytes)
	return decryptedString, nil
}

func getDerivedKey(password string, salt []byte, count int) ([]byte, []byte) {
	key := md5.Sum([]byte(password + string(salt)))
	for i := 0; i < count-1; i++ {
		key = md5.Sum(key[:])
	}
	return key[:8], key[8:]
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/993779.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存