Skip to content

Commit

Permalink
增加DES加解密
Browse files Browse the repository at this point in the history
  • Loading branch information
steden committed Nov 9, 2024
1 parent 334187f commit f8d618b
Show file tree
Hide file tree
Showing 4 changed files with 214 additions and 19 deletions.
106 changes: 106 additions & 0 deletions encrypt/aes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package encrypt

import (
"bytes"
"crypto/aes"
"encoding/base64"
"encoding/hex"
)

// AESEncrypt AES加密
func AESEncrypt(key string, plaintext string) string {
// create cipher
c, err := aes.NewCipher([]byte(key))
if err != nil {
return ""
}
// allocate space for ciphered data
out := make([]byte, len(plaintext))

// encrypt
c.Encrypt(out, []byte(plaintext))

// return hex string
return hex.EncodeToString(out)
}

// AESDecrypt AES解密
func AESDecrypt(key string, decodeString string) string {
ciphertext, _ := hex.DecodeString(decodeString)

c, err := aes.NewCipher([]byte(key))
if err != nil {
return ""
}

pt := make([]byte, len(ciphertext))
c.Decrypt(pt, ciphertext)

return string(pt)
}

// 加密
func AesEncryptByECB(data, key string) string {
// 判断key长度
keyLenMap := map[int]struct{}{16: {}, 24: {}, 32: {}}
if _, ok := keyLenMap[len(key)]; !ok {
panic("key长度必须是 16、24、32 其中一个")
}
// 密钥和待加密数据转成[]byte
originByte := []byte(data)
keyByte := []byte(key)
// 创建密码组,长度只能是16、24、32字节
block, _ := aes.NewCipher(keyByte)
// 获取密钥长度
blockSize := block.BlockSize()
// 补码
originByte = PKCS7Padding(originByte, blockSize)
// 创建保存加密变量
encryptResult := make([]byte, len(originByte))
// CEB是把整个明文分成若干段相同的小段,然后对每一小段进行加密
for bs, be := 0, blockSize; bs < len(originByte); bs, be = bs+blockSize, be+blockSize {
block.Encrypt(encryptResult[bs:be], originByte[bs:be])
}
return base64.StdEncoding.EncodeToString(encryptResult)
}

// 解密
func AesDecryptByECB(data, key string) string {
// 判断key长度
keyLenMap := map[int]struct{}{16: {}, 24: {}, 32: {}}
if _, ok := keyLenMap[len(key)]; !ok {
panic("key长度必须是 16、24、32 其中一个")
}
// 反解密码base64
originByte, _ := base64.StdEncoding.DecodeString(data)
// 密钥和待加密数据转成[]byte
keyByte := []byte(key)
// 创建密码组,长度只能是16、24、32字节
block, _ := aes.NewCipher(keyByte)
// 获取密钥长度
blockSize := block.BlockSize()
// 创建保存解密变量
decrypted := make([]byte, len(originByte))
for bs, be := 0, blockSize; bs < len(originByte); bs, be = bs+blockSize, be+blockSize {
block.Decrypt(decrypted[bs:be], originByte[bs:be])
}
// 解码
return string(PKCS7UNPadding(decrypted))
}

// 解码
func PKCS7UNPadding(originDataByte []byte) []byte {
length := len(originDataByte)
unpadding := int(originDataByte[length-1])
return originDataByte[:(length - unpadding)]
}

// 补码
func PKCS7Padding(originByte []byte, blockSize int) []byte {
// 计算补码长度
padding := blockSize - len(originByte)%blockSize
// 生成补码
padText := bytes.Repeat([]byte{byte(padding)}, padding)
// 追加补码
return append(originByte, padText...)
}
69 changes: 69 additions & 0 deletions encrypt/des.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package encrypt

import (
"bytes"
"crypto/des"
"encoding/base64"
)

// 加密函数
func DESEncrypt(plainText string, key string) string {
block, err := des.NewCipher([]byte(key))
if err != nil {
return ""
}

// PKCS7 填充
paddedText := pad([]byte(plainText), block.BlockSize())
cipherText := make([]byte, len(paddedText))

// 使用 ECB 模式
for i := 0; i < len(paddedText); i += block.BlockSize() {
block.Encrypt(cipherText[i:i+block.BlockSize()], paddedText[i:i+block.BlockSize()])
}

// 返回 Base64 编码的密文
return base64.StdEncoding.EncodeToString(cipherText)
}

// 解密函数
func DESDecrypt(cipherText string, key string) string {
ciphertext, err := base64.StdEncoding.DecodeString(cipherText)
if err != nil {
return ""
}

block, err := des.NewCipher([]byte(key))
if err != nil {
return ""
}

if len(ciphertext)%block.BlockSize() != 0 {
//return "", errors.New("ciphertext is not a multiple of the block size")
return ""
}

plainText := make([]byte, len(ciphertext))

// 使用 ECB 模式解密
for i := 0; i < len(ciphertext); i += block.BlockSize() {
block.Decrypt(plainText[i:i+block.BlockSize()], ciphertext[i:i+block.BlockSize()])
}

// 去掉填充
return string(unpad(plainText))
}

// PKCS7 填充
func pad(data []byte, blockSize int) []byte {
padding := blockSize - len(data)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(data, padtext...)
}

// 去除填充
func unpad(data []byte) []byte {
length := len(data)
unpadding := int(data[length-1])
return data[:(length - unpadding)]
}
39 changes: 39 additions & 0 deletions test/encrypt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package test

import (
"testing"

"github.com/farseer-go/utils/encrypt"
"github.com/stretchr/testify/assert"
)

// CopyFolder
func TestMd5(t *testing.T) {
s := encrypt.Md5("123")
assert.Equal(t, "202cb962ac59075b964b07152d234b70", s)
}

// CopyFolder
func TestSha1(t *testing.T) {
s := encrypt.Sha1("abc")
assert.Equal(t, "a9993e364706816aba3e25717850c26c9cd0d89d", s)
}

// CopyFolder
func TestAES(t *testing.T) {
// 加解密
s := encrypt.AesEncryptByECB("hello world", "sqNWnLg7Y7dQbH6Y")
content := encrypt.AesDecryptByECB(s, "sqNWnLg7Y7dQbH6Y")
assert.Equal(t, "hello world", content)
}

// CopyFolder
func TestDES(t *testing.T) {
// 加解密
s := encrypt.DESEncrypt("hello world", "sqNWnLg7")
content := encrypt.DESDecrypt(s, "sqNWnLg7")
assert.Equal(t, "hello world", content)

content = encrypt.DESDecrypt("GB3x+HDVotbZ3aAXvAB6mQ==", "sqNWnLg7")
assert.Equal(t, "hello world", content)
}
19 changes: 0 additions & 19 deletions test/md5_test.go

This file was deleted.

0 comments on commit f8d618b

Please sign in to comment.