mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
增加对DES算法的封装
This commit is contained in:
289
g/encoding/gdes/gdes.go
Normal file
289
g/encoding/gdes/gdes.go
Normal file
@ -0,0 +1,289 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
package gdes
|
||||
|
||||
import (
|
||||
"crypto/des"
|
||||
"crypto/cipher"
|
||||
"errors"
|
||||
"bytes"
|
||||
)
|
||||
|
||||
const (
|
||||
NOPADDING = iota
|
||||
PKCS5PADDING
|
||||
)
|
||||
|
||||
//ECB模式DES加密
|
||||
func DesECBEncrypt(key []byte, clearText []byte, padding int) ([]byte, error) {
|
||||
text, err := Padding(clearText, padding)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cipherText := make([]byte, len(text))
|
||||
|
||||
block, err := des.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blockSize := block.BlockSize()
|
||||
for i, count := 0, len(text)/blockSize; i < count; i++ {
|
||||
begin, end := i * blockSize, i * blockSize + blockSize
|
||||
block.Encrypt(cipherText[begin:end], text[begin:end])
|
||||
}
|
||||
return cipherText, nil
|
||||
}
|
||||
|
||||
//ECB模式DES解密
|
||||
func DesECBDecrypt(key []byte, cipherText []byte, padding int) ([]byte, error) {
|
||||
text := make([]byte, len(cipherText))
|
||||
block, err := des.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blockSize := block.BlockSize()
|
||||
for i, count := 0, len(text)/blockSize; i < count; i++{
|
||||
begin, end := i * blockSize, i * blockSize + blockSize
|
||||
block.Decrypt(text[begin:end], cipherText[begin:end])
|
||||
}
|
||||
|
||||
clearText, err := UnPadding(text, padding)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clearText, nil
|
||||
}
|
||||
|
||||
//ECB模式3DES加密,密钥长度可以是16或24位长
|
||||
func TripleDesECBEncrypt(key []byte, clearText []byte, padding int) ( []byte, error) {
|
||||
if len(key) != 16 && len(key) != 24 {
|
||||
return nil, errors.New("key length error")
|
||||
}
|
||||
|
||||
text, err := Padding(clearText, padding)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newKey := make([]byte, 0)
|
||||
if len(key) == 16 {
|
||||
newKey = append([]byte{}, key...)
|
||||
newKey = append(newKey, key[:8]...)
|
||||
} else {
|
||||
newKey = append([]byte{}, key...)
|
||||
}
|
||||
|
||||
block, err := des.NewTripleDESCipher(newKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blockSize := block.BlockSize()
|
||||
cipherText := make([]byte, len(text))
|
||||
for i, count := 0, len(text) / blockSize; i < count; i++{
|
||||
begin, end := i * blockSize, i * blockSize + blockSize
|
||||
block.Encrypt(cipherText[begin:end], text[begin:end])
|
||||
}
|
||||
return cipherText, nil
|
||||
}
|
||||
|
||||
//ECB模式3DES解密,密钥长度可以是16或24位长
|
||||
func TripleDesECBDecrypt(key []byte, cipherText []byte, padding int) ([]byte, error) {
|
||||
if len(key) != 16 && len(key) != 24 {
|
||||
return nil, errors.New("key length error")
|
||||
}
|
||||
|
||||
newKey := make([]byte, 0)
|
||||
if len(key) == 16 {
|
||||
newKey = append([]byte{}, key...)
|
||||
newKey = append(newKey, key[:8]...)
|
||||
} else {
|
||||
newKey = append([]byte{}, key...)
|
||||
}
|
||||
|
||||
block, err := des.NewTripleDESCipher(newKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blockSize := block.BlockSize()
|
||||
text := make([]byte, len(cipherText))
|
||||
for i, count := 0, len(text) / blockSize; i < count; i++ {
|
||||
begin, end := i * blockSize, i * blockSize + blockSize
|
||||
block.Decrypt(text[begin:end], cipherText[begin:end])
|
||||
}
|
||||
|
||||
clearText, err := UnPadding(text, padding)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clearText, nil
|
||||
}
|
||||
|
||||
//CBC模式DES加密
|
||||
func DesCBCEncrypt(key []byte, clearText []byte, iv []byte, padding int) ([]byte, error) {
|
||||
block, err := des.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(iv) != block.BlockSize() {
|
||||
return nil, errors.New("iv length invalid")
|
||||
}
|
||||
|
||||
text, err := Padding(clearText, padding)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cipherText := make([]byte, len(text))
|
||||
|
||||
encrypter := cipher.NewCBCEncrypter(block, iv)
|
||||
encrypter.CryptBlocks(cipherText, text)
|
||||
|
||||
return cipherText, nil
|
||||
}
|
||||
|
||||
//CBC模式DES解密
|
||||
func DesCBCDecrypt(key []byte, cipherText []byte, iv []byte, padding int) ([]byte, error) {
|
||||
block, err := des.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(iv) != block.BlockSize() {
|
||||
return nil, errors.New("iv length invalid")
|
||||
}
|
||||
|
||||
text := make([]byte, len(cipherText))
|
||||
decrypter := cipher.NewCBCDecrypter(block, iv)
|
||||
decrypter.CryptBlocks(text, cipherText)
|
||||
|
||||
clearText, err := UnPadding(text, padding)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return clearText, nil
|
||||
}
|
||||
|
||||
//CBC模式3DES加密
|
||||
func TripleDesCBCEncrypt(key []byte, clearText []byte, iv []byte, padding int) ([]byte, error) {
|
||||
if len(key) != 16 && len(key) != 24 {
|
||||
return nil, errors.New("key length invalid")
|
||||
}
|
||||
|
||||
newKey := make([]byte, 0)
|
||||
if len(key) == 16 {
|
||||
newKey = append([]byte{}, key...)
|
||||
newKey = append(newKey, key[:8]...)
|
||||
} else {
|
||||
newKey = append([]byte{}, key...)
|
||||
}
|
||||
|
||||
block, err := des.NewTripleDESCipher(newKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(iv) != block.BlockSize() {
|
||||
return nil, errors.New("iv length invalid")
|
||||
}
|
||||
|
||||
text, err := Padding(clearText, padding)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cipherText := make([]byte, len(text))
|
||||
encrypter := cipher.NewCBCEncrypter(block, iv)
|
||||
encrypter.CryptBlocks(cipherText, text)
|
||||
|
||||
return cipherText, nil
|
||||
}
|
||||
|
||||
//CBC模式3DES解密
|
||||
func TripleDesCBCDecrypt(key []byte, cipherText []byte, iv []byte, padding int) ( []byte, error) {
|
||||
if len(key) != 16 && len(key) != 24 {
|
||||
return nil, errors.New("key length invalid")
|
||||
}
|
||||
|
||||
newKey := make([]byte, 0)
|
||||
if len(key) == 16 {
|
||||
newKey = append([]byte{}, key...)
|
||||
newKey = append(newKey, key[:8]...)
|
||||
} else {
|
||||
newKey = append([]byte{}, key...)
|
||||
}
|
||||
|
||||
block, err := des.NewTripleDESCipher(newKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(iv) != block.BlockSize() {
|
||||
return nil, errors.New("iv length invalid")
|
||||
}
|
||||
|
||||
text := make([]byte, len(cipherText))
|
||||
decrypter := cipher.NewCBCDecrypter(block, iv)
|
||||
decrypter.CryptBlocks(text, cipherText)
|
||||
|
||||
clearText, err := UnPadding(text, padding)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return clearText, nil
|
||||
}
|
||||
|
||||
//PKCS5补位
|
||||
func PKCS5Padding(text []byte, blockSize int) []byte {
|
||||
padding := blockSize - len(text) % blockSize
|
||||
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||
return append(text, padtext...)
|
||||
}
|
||||
|
||||
//去除PKCS5补位
|
||||
func PKCS5Unpadding(text []byte) []byte{
|
||||
length := len(text)
|
||||
padtext := int(text[length - 1])
|
||||
return text[:(length - padtext)]
|
||||
}
|
||||
|
||||
//补位方法
|
||||
func Padding(text []byte, padding int)([]byte, error) {
|
||||
switch padding {
|
||||
case NOPADDING:
|
||||
if len(text) % 8 != 0 {
|
||||
return nil, errors.New("text length invalid")
|
||||
}
|
||||
case PKCS5PADDING:
|
||||
return PKCS5Padding(text, 8), nil
|
||||
default:
|
||||
return nil, errors.New("padding type error")
|
||||
}
|
||||
|
||||
return text, nil
|
||||
}
|
||||
|
||||
//去除补位方法
|
||||
func UnPadding(text []byte, padding int)([]byte, error) {
|
||||
switch padding {
|
||||
case NOPADDING:
|
||||
if len(text) % 8 != 0 {
|
||||
return nil, errors.New("text length invalid")
|
||||
}
|
||||
case PKCS5PADDING:
|
||||
return PKCS5Unpadding(text), nil
|
||||
default:
|
||||
return nil, errors.New("padding type error.")
|
||||
}
|
||||
return text, nil
|
||||
}
|
||||
184
g/encoding/gdes/gdes_test.go
Normal file
184
g/encoding/gdes/gdes_test.go
Normal file
@ -0,0 +1,184 @@
|
||||
package gdes
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func TestDesECB(t *testing.T){
|
||||
{
|
||||
key := []byte("11111111")
|
||||
text := []byte("12345678")
|
||||
padding := NOPADDING
|
||||
cipherText, err := DesECBEncrypt(key, text, padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
clearText, err := DesECBDecrypt(key, cipherText, padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if bytes.Equal(clearText, text) == false {
|
||||
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
|
||||
}
|
||||
fmt.Println("clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
key := []byte("11111111")
|
||||
text := []byte("12345678")
|
||||
padding := PKCS5PADDING
|
||||
cipherText, err := DesECBEncrypt(key, text, padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
clearText, err := DesECBDecrypt(key, cipherText, padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if bytes.Equal(clearText, text) == false {
|
||||
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
|
||||
}
|
||||
fmt.Println("clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
|
||||
}
|
||||
}
|
||||
|
||||
func Test3DesECB(t *testing.T){
|
||||
{
|
||||
key := []byte("1111111111111234")
|
||||
text := []byte("1234567812345678")
|
||||
padding := NOPADDING
|
||||
cipherText, err := TripleDesECBEncrypt(key, text, padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
clearText, err := TripleDesECBDecrypt(key, cipherText, padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if bytes.Equal(clearText, text) == false {
|
||||
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
|
||||
}
|
||||
fmt.Println("key:", hex.EncodeToString(key),"clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
key := []byte("111111111111123412345678")
|
||||
text := []byte("123456789")
|
||||
padding := PKCS5PADDING
|
||||
cipherText, err := TripleDesECBEncrypt(key, text, padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
clearText, err := TripleDesECBDecrypt(key, cipherText, padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if bytes.Equal(clearText, text) == false {
|
||||
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
|
||||
}
|
||||
fmt.Println("key:", hex.EncodeToString(key),"clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDesCBC(t *testing.T){
|
||||
{
|
||||
key := []byte("11111111")
|
||||
text := []byte("1234567812345678")
|
||||
padding := NOPADDING
|
||||
iv := []byte("12345678")
|
||||
cipherText, err := DesCBCEncrypt(key, text, iv,padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
clearText, err := DesCBCDecrypt(key, cipherText, iv, padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if bytes.Equal(clearText, text) == false {
|
||||
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
|
||||
}
|
||||
fmt.Println("key:", hex.EncodeToString(key),"clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
key := []byte("11111111")
|
||||
text := []byte("12345678")
|
||||
padding := PKCS5PADDING
|
||||
iv := []byte("12345678")
|
||||
cipherText, err := DesCBCEncrypt(key, text, iv, padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
clearText, err := DesCBCDecrypt(key, cipherText, iv, padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if bytes.Equal(clearText, text) == false {
|
||||
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
|
||||
}
|
||||
fmt.Println("key:", hex.EncodeToString(key),"clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
|
||||
}
|
||||
}
|
||||
|
||||
func Test3DesCBC(t *testing.T){
|
||||
{
|
||||
key := []byte("1111111112345678")
|
||||
text := []byte("1234567812345678")
|
||||
padding := NOPADDING
|
||||
iv := []byte("12345678")
|
||||
cipherText, err := TripleDesCBCEncrypt(key, text, iv,padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
clearText, err := TripleDesCBCDecrypt(key, cipherText, iv, padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if bytes.Equal(clearText, text) == false {
|
||||
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
|
||||
}
|
||||
fmt.Println("key:", hex.EncodeToString(key),"clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
key := []byte("111111111234567812345678")
|
||||
text := []byte("12345678")
|
||||
padding := PKCS5PADDING
|
||||
iv := []byte("12345678")
|
||||
cipherText, err := TripleDesCBCEncrypt(key, text, iv, padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
clearText, err := TripleDesCBCDecrypt(key, cipherText, iv, padding)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if bytes.Equal(clearText, text) == false {
|
||||
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
|
||||
}
|
||||
fmt.Println("key:", hex.EncodeToString(key),"clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user