Reputation: 305
I really need to implement 3DES/ECB/PKCS5Padding for Golang, which I found for implementation like https://gist.github.com/cuixin/10612934 but my secret key length is 32 bytes and is not working. I need your help, guys. Thank you very much
Upvotes: 2
Views: 2353
Reputation: 314
3DES The 3DES algorithm uses a 24-byte length key to divide the key into 3 sub-keys of 8 bytes: K1, K2, K3. Use these 3 keys to encrypt and decrypt plaintext, as follows: E (K,d), D (k,d), respectively, uses the key k to encrypt or decrypt data d, returning the encrypted or decrypted data.
3DES Encryption Process: E(k3,D(k2,E(k1,d))) The meaning is: will clear text D first uses K1 to encrypt, obtains the ciphertext D1, to D1 again uses K2 to do the decryption processing, obtains the ciphertext D2; then the D2 uses the K3 to do the encryption processing, obtains the final cipher text. The 3DES decryption process is the opposite of encryption: D(k1,E(k2,D(k3,d))) The ciphertext d is decrypted with K3, the ciphertext is D1, the D1 is encrypted with K2, the cipher is D2, and the D2 is decrypted with K1, and the final plaintext is obtained.
You can try this code witch is compatiable with your gist code:
package main
import (
"bytes"
"crypto/des"
"errors"
"fmt"
"log"
)
//ECB PKCS5Padding
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
//ECB PKCS5Unpadding
func PKCS5Unpadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
//Des encryption
func encrypt(origData, key []byte) ([]byte, error) {
if len(origData) < 1 || len(key) < 1 {
return nil, errors.New("wrong data or key")
}
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
bs := block.BlockSize()
if len(origData)%bs != 0 {
return nil, errors.New("wrong padding")
}
out := make([]byte, len(origData))
dst := out
for len(origData) > 0 {
block.Encrypt(dst, origData[:bs])
origData = origData[bs:]
dst = dst[bs:]
}
return out, nil
}
//Des Decrypt
func decrypt(crypted, key []byte) ([]byte, error) {
if len(crypted) < 1 || len(key) < 1 {
return nil, errors.New("wrong data or key")
}
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
out := make([]byte, len(crypted))
dst := out
bs := block.BlockSize()
if len(crypted)%bs != 0 {
return nil, errors.New("wrong crypted size")
}
for len(crypted) > 0 {
block.Decrypt(dst, crypted[:bs])
crypted = crypted[bs:]
dst = dst[bs:]
}
return out, nil
}
//[golang ECB 3DES Encrypt]
func TripleEcbDesEncrypt(origData, key []byte) ([]byte, error) {
tkey := make([]byte, 24, 24)
copy(tkey, key)
k1 := tkey[:8]
k2 := tkey[8:16]
k3 := tkey[16:]
block, err := des.NewCipher(k1)
if err != nil {
return nil, err
}
bs := block.BlockSize()
origData = PKCS5Padding(origData, bs)
buf1, err := encrypt(origData, k1)
if err != nil {
return nil, err
}
buf2, err := decrypt(buf1, k2)
if err != nil {
return nil, err
}
out, err := encrypt(buf2, k3)
if err != nil {
return nil, err
}
return out, nil
}
//[golang ECB 3DES Decrypt]
func TripleEcbDesDecrypt(crypted, key []byte) ([]byte, error) {
tkey := make([]byte, 24, 24)
copy(tkey, key)
k1 := tkey[:8]
k2 := tkey[8:16]
k3 := tkey[16:]
buf1, err := decrypt(crypted, k3)
if err != nil {
return nil, err
}
buf2, err := encrypt(buf1, k2)
if err != nil {
return nil, err
}
out, err := decrypt(buf2, k1)
if err != nil {
return nil, err
}
out = PKCS5Unpadding(out)
return out, nil
}
func main() {
key2 := []byte("5e8487e65e8487e65e8487e6")
origtext2 := []byte("hello world123563332")
erytext2, err := TripleEcbDesEncrypt(origtext2, key2)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%v\n", origtext2)
destext2, err2 := TripleEcbDesDecrypt(erytext2, key2)
if err2 != nil {
log.Fatal(err2)
}
fmt.Println(string(destext2))
fmt.Println(len(origtext2), len(string(destext2)))
fmt.Println(string(origtext2) == string(destext2))
}
Upvotes: 3