Files
2026-05-27 23:03:00 +08:00

85 lines
1.7 KiB
Go

package pbkd
import (
"errors"
"xdx.jelly/xgcl/sm/sm4"
"xdx.jelly/xgcl/utils/padding"
)
const (
ENCRYPT = iota
DECRYPT
)
type Pbeser interface {
// EncryptBlocks
EncryptBlocks(dst, src []byte) ([]byte, error)
DecryptBlocks(dst, src []byte) ([]byte, error)
EncryptWithPadding(src []byte) ([]byte, error)
DecryptWithPadding(src []byte) ([]byte, error)
ResetIv(iv []byte) error
}
type PbesWithSm4Cbc struct {
key []byte
iv []byte
}
var errOperation = errors.New("error operation")
var errInvalidIV = errors.New("invalid iv length")
func NewPbesWithSm4Cbc(password, salt []byte, count int, iv []byte) (Pbeser, error) {
key, err := PbkdfWithHmacSm3(password, salt, count, int64(sm4.BlockSize))
if err != nil {
return nil, err
}
if len(iv) != sm4.BlockSize {
return nil, errInvalidIV
}
myIv := make([]byte, sm4.BlockSize)
copy(myIv, iv)
return &PbesWithSm4Cbc{
key: key,
iv: myIv,
}, nil
}
func (pbes *PbesWithSm4Cbc) EncryptBlocks(dst, src []byte) ([]byte, error) {
return sm4.EncryptCBC(dst, pbes.iv, pbes.key, src)
}
func (pbes *PbesWithSm4Cbc) DecryptBlocks(dst, src []byte) ([]byte, error) {
return sm4.EncryptCBC(dst, pbes.iv, pbes.key, src)
}
func (pbes *PbesWithSm4Cbc) EncryptWithPadding(src []byte) ([]byte, error) {
pad := padding.P7.Pad(src, sm4.BlockSize)
return sm4.EncryptCBC(nil, pbes.iv, pbes.key, pad)
}
func (pbes *PbesWithSm4Cbc) DecryptWithPadding(src []byte) ([]byte, error) {
dst, err := sm4.DecryptCBC(nil, pbes.iv, pbes.key, src)
if err != nil {
return nil, err
}
dst, err = padding.P7.Unpad(dst, sm4.BlockSize)
if err != nil {
return nil, err
}
return dst, nil
}
func (pbes *PbesWithSm4Cbc) ResetIv(iv []byte) error {
if len(iv) != sm4.BlockSize {
return errInvalidIV
}
copy(pbes.iv, iv)
return nil
}