golang 解析 jasypt 加密

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:]
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值