1 Star 0 Fork 0

余济舟/util

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
ecb.go 4.88 KB
一键复制 编辑 原始数据 按行查看 历史
余济舟 提交于 2024-08-09 17:14 . [optimize]适配v2发型版本号
package symmetric
import (
"bytes"
"crypto/aes"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"gitee.com/jericho-yu/util/v2/str"
"gitee.com/jericho-yu/util/v2/zip"
)
type (
Ecb struct{}
Source struct {
Username string `json:"username"`
Password string `json:"password"`
}
)
var EcbHelper Ecb
func (Ecb) New() *Ecb { return &Ecb{} }
// padPKCS7 pads the plaintext to be a multiple of the block size
func (Ecb) padPKCS7(plaintext []byte, blockSize int) []byte {
padding := blockSize - len(plaintext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(plaintext, padtext...)
}
// unPadPKCS7 removes the padding from the decrypted text
func (Ecb) unPadPKCS7(plaintext []byte) []byte {
length := len(plaintext)
unpadding := int(plaintext[length-1])
return plaintext[:(length - unpadding)]
}
func (Ecb) unPadPKCS72(src []byte, blockSize int) ([]byte, error) {
length := len(src)
if blockSize <= 0 {
return nil, fmt.Errorf("invalid blockSize: %d", blockSize)
}
if length%blockSize != 0 || length == 0 {
return nil, errors.New("invalid data len")
}
unpadding := int(src[length-1])
if unpadding > blockSize {
return nil, fmt.Errorf("invalid unpadding: %d", unpadding)
}
if unpadding == 0 {
return nil, errors.New("invalid unpadding: 0")
}
padding := src[length-unpadding:]
for i := 0; i < unpadding; i++ {
if padding[i] != byte(unpadding) {
return nil, errors.New("invalid padding")
}
}
return src[:(length - unpadding)], nil
}
// Encrypt encrypts plaintext using AES in ECB mode
func (Ecb) Encrypt(plaintext, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
plaintext = EcbHelper.padPKCS7(plaintext, blockSize)
cipherText := make([]byte, len(plaintext))
for start := 0; start < len(plaintext); start += blockSize {
block.Encrypt(cipherText[start:start+blockSize], plaintext[start:start+blockSize])
}
return cipherText, nil
}
// Decrypt decrypts cipherText using AES in ECB mode
func (Ecb) Decrypt(cipherText, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
if len(cipherText)%blockSize != 0 {
return nil, fmt.Errorf("cipherText is not a multiple of the block size")
}
plaintext := make([]byte, len(cipherText))
for start := 0; start < len(cipherText); start += blockSize {
block.Decrypt(plaintext[start:start+blockSize], cipherText[start:start+blockSize])
}
return EcbHelper.unPadPKCS72(plaintext, blockSize)
}
// encrypt
func encrypt(plaintext, key []byte) string {
// step1: zip
zipped, zipErr := zip.ZlibHelper.Compress(plaintext)
if zipErr != nil {
str.StrHelper.LogError("[ECB] compressing data: %v", zipErr)
}
str.StrHelper.Log("[ECB] zipped")
// step2: aes-ecb-encrypt
encrypted, encryptErr := EcbHelper.Encrypt(zipped, key)
if encryptErr != nil {
str.StrHelper.LogError("[ECB] encrypting data:%v", encryptErr)
}
str.StrHelper.Log("[ECB] encrypted")
// step3: encode base64
encodeBase64 := base64.StdEncoding.EncodeToString(encrypted)
str.StrHelper.Log("[ECB] encode base64")
return encodeBase64
}
// decrypt
func decrypt(cipherText, key []byte) []byte {
// step1: decode base64
decodeBase64, decodeBase64Err := base64.StdEncoding.DecodeString(string(cipherText))
if decodeBase64Err != nil {
str.StrHelper.LogError("[ECB] decode base64: %v", decodeBase64Err)
}
str.StrHelper.Log("[ECB] decode base64")
// step2: aes-ecb-decrypt
decrypted, decryptErr := EcbHelper.Decrypt(decodeBase64, key)
if decryptErr != nil {
str.StrHelper.LogError("[ECB] decrypting data: %v", decryptErr)
}
str.StrHelper.Log("[ECB] decrypted")
// step3: unzip
unzipped, unzipErr := zip.ZlibHelper.Decompress(decrypted)
if unzipErr != nil {
str.StrHelper.LogError("[ECB] unzipping data: %v", unzipErr)
}
str.StrHelper.Log("[ECB] unzipped")
return unzipped
}
func (Ecb) Demo() {
key, keyErr := base64.StdEncoding.DecodeString("87dwQRkoNFNoIcq1A+zFHA==")
if keyErr != nil {
str.StrHelper.New().LogError("[ECB] key decode base64: %v", keyErr)
}
key2, key2Err := base64.StdEncoding.DecodeString("tjp5OPIU1ETF5s33fsLWdA==")
if key2Err != nil {
str.StrHelper.New().LogError("[ECB] key2 decode base64: %v", key2Err)
}
switch plaintext, jsonErr := json.Marshal(Source{Username: "abc123", Password: "cba321"}); {
case jsonErr != nil:
str.StrHelper.LogError("[ECB] json marshal: %v", jsonErr)
default:
str.StrHelper.Log("[ECB] json marshal: %s", plaintext)
// encrypt
encrypted := encrypt(plaintext, key)
str.StrHelper.LogSuccess("[ECB] encrypted: %s", encrypted)
// decrypt
// decrypted := decrypt([]byte(encrypted), key)
decrypted := decrypt([]byte("Yw0Fh8699WC0hvKCRcFinq9nDqLdoECXZ5ZFK3onuXtzR61QKEvAH4+7NI4xYsn1eLwFOhzf0eBHnXv1ZaeWdueOy+t/OpgMXxl64s2PqLDRE8z+z2mHUVpvb7/V/2cS"), key2)
str.StrHelper.LogSuccess("[ECB] decrypted: %s", string(decrypted))
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/jericho-yu/util.git
git@gitee.com:jericho-yu/util.git
jericho-yu
util
util
v2.2.7

搜索帮助