mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-05-10 16:30:01 +08:00
fix: critical security fixes in core/codec (S0) (#5479)
This commit is contained in:
@@ -6,8 +6,6 @@ import (
|
||||
"crypto/cipher"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
// ErrPaddingSize indicates bad padding size.
|
||||
@@ -27,7 +25,8 @@ func newECB(b cipher.Block) *ecb {
|
||||
|
||||
type ecbEncrypter ecb
|
||||
|
||||
// NewECBEncrypter returns an ECB encrypter.
|
||||
// Deprecated: NewECBEncrypter returns an ECB encrypter.
|
||||
// ECB mode is insecure for multi-block data. Use AES-GCM instead.
|
||||
func NewECBEncrypter(b cipher.Block) cipher.BlockMode {
|
||||
return (*ecbEncrypter)(newECB(b))
|
||||
}
|
||||
@@ -39,12 +38,10 @@ func (x *ecbEncrypter) BlockSize() int { return x.blockSize }
|
||||
// the block size. Dst and src must overlap entirely or not at all.
|
||||
func (x *ecbEncrypter) CryptBlocks(dst, src []byte) {
|
||||
if len(src)%x.blockSize != 0 {
|
||||
logx.Error("crypto/cipher: input not full blocks")
|
||||
return
|
||||
panic("crypto/cipher: input not full blocks")
|
||||
}
|
||||
if len(dst) < len(src) {
|
||||
logx.Error("crypto/cipher: output smaller than input")
|
||||
return
|
||||
panic("crypto/cipher: output smaller than input")
|
||||
}
|
||||
|
||||
for len(src) > 0 {
|
||||
@@ -56,7 +53,8 @@ func (x *ecbEncrypter) CryptBlocks(dst, src []byte) {
|
||||
|
||||
type ecbDecrypter ecb
|
||||
|
||||
// NewECBDecrypter returns an ECB decrypter.
|
||||
// Deprecated: NewECBDecrypter returns an ECB decrypter.
|
||||
// ECB mode is insecure for multi-block data. Use AES-GCM instead.
|
||||
func NewECBDecrypter(b cipher.Block) cipher.BlockMode {
|
||||
return (*ecbDecrypter)(newECB(b))
|
||||
}
|
||||
@@ -70,12 +68,10 @@ func (x *ecbDecrypter) BlockSize() int {
|
||||
// the block size. Dst and src must overlap entirely or not at all.
|
||||
func (x *ecbDecrypter) CryptBlocks(dst, src []byte) {
|
||||
if len(src)%x.blockSize != 0 {
|
||||
logx.Error("crypto/cipher: input not full blocks")
|
||||
return
|
||||
panic("crypto/cipher: input not full blocks")
|
||||
}
|
||||
if len(dst) < len(src) {
|
||||
logx.Error("crypto/cipher: output smaller than input")
|
||||
return
|
||||
panic("crypto/cipher: output smaller than input")
|
||||
}
|
||||
|
||||
for len(src) > 0 {
|
||||
@@ -85,14 +81,18 @@ func (x *ecbDecrypter) CryptBlocks(dst, src []byte) {
|
||||
}
|
||||
}
|
||||
|
||||
// EcbDecrypt decrypts src with the given key.
|
||||
// Deprecated: EcbDecrypt decrypts src with the given key.
|
||||
// ECB mode is insecure for multi-block data. Use AES-GCM instead.
|
||||
func EcbDecrypt(key, src []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
logx.Errorf("Decrypt key error: % x", key)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(src)%block.BlockSize() != 0 {
|
||||
return nil, ErrPaddingSize
|
||||
}
|
||||
|
||||
decrypter := NewECBDecrypter(block)
|
||||
decrypted := make([]byte, len(src))
|
||||
decrypter.CryptBlocks(decrypted, src)
|
||||
@@ -100,8 +100,9 @@ func EcbDecrypt(key, src []byte) ([]byte, error) {
|
||||
return pkcs5Unpadding(decrypted, decrypter.BlockSize())
|
||||
}
|
||||
|
||||
// EcbDecryptBase64 decrypts base64 encoded src with the given base64 encoded key.
|
||||
// Deprecated: EcbDecryptBase64 decrypts base64 encoded src with the given base64 encoded key.
|
||||
// The returned string is also base64 encoded.
|
||||
// ECB mode is insecure for multi-block data. Use AES-GCM instead.
|
||||
func EcbDecryptBase64(key, src string) (string, error) {
|
||||
keyBytes, err := getKeyBytes(key)
|
||||
if err != nil {
|
||||
@@ -121,11 +122,11 @@ func EcbDecryptBase64(key, src string) (string, error) {
|
||||
return base64.StdEncoding.EncodeToString(decryptedBytes), nil
|
||||
}
|
||||
|
||||
// EcbEncrypt encrypts src with the given key.
|
||||
// Deprecated: EcbEncrypt encrypts src with the given key.
|
||||
// ECB mode is insecure for multi-block data. Use AES-GCM instead.
|
||||
func EcbEncrypt(key, src []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
logx.Errorf("Encrypt key error: % x", key)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -137,8 +138,9 @@ func EcbEncrypt(key, src []byte) ([]byte, error) {
|
||||
return crypted, nil
|
||||
}
|
||||
|
||||
// EcbEncryptBase64 encrypts base64 encoded src with the given base64 encoded key.
|
||||
// Deprecated: EcbEncryptBase64 encrypts base64 encoded src with the given base64 encoded key.
|
||||
// The returned string is also base64 encoded.
|
||||
// ECB mode is insecure for multi-block data. Use AES-GCM instead.
|
||||
func EcbEncryptBase64(key, src string) (string, error) {
|
||||
keyBytes, err := getKeyBytes(key)
|
||||
if err != nil {
|
||||
@@ -179,10 +181,20 @@ func pkcs5Padding(ciphertext []byte, blockSize int) []byte {
|
||||
|
||||
func pkcs5Unpadding(src []byte, blockSize int) ([]byte, error) {
|
||||
length := len(src)
|
||||
unpadding := int(src[length-1])
|
||||
if unpadding >= length || unpadding > blockSize {
|
||||
if length == 0 {
|
||||
return nil, ErrPaddingSize
|
||||
}
|
||||
|
||||
unpadding := int(src[length-1])
|
||||
if unpadding < 1 || unpadding > blockSize || unpadding > length {
|
||||
return nil, ErrPaddingSize
|
||||
}
|
||||
|
||||
for _, b := range src[length-unpadding:] {
|
||||
if int(b) != unpadding {
|
||||
return nil, ErrPaddingSize
|
||||
}
|
||||
}
|
||||
|
||||
return src[:length-unpadding], nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user