Skip to content

Instantly share code, notes, and snippets.

@jpralves
Created April 28, 2018 21:08
Show Gist options
  • Save jpralves/2c2606e4739ba0122d9c1c0069fa8df0 to your computer and use it in GitHub Desktop.
Save jpralves/2c2606e4739ba0122d9c1c0069fa8df0 to your computer and use it in GitHub Desktop.
package main
import (
"crypto/cipher"
"crypto/des"
"fmt"
"bytes"
"encoding/base64"
"crypto/md5"
"errors"
"os"
"math/rand"
"time"
)
func DesEncryption(key, iv, plainText []byte) ([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
origData := PKCS5Padding(plainText, blockSize)
blockMode := cipher.NewCBCEncrypter(block, iv)
cryted := make([]byte, len(origData))
blockMode.CryptBlocks(cryted, origData)
return cryted, nil
}
func DesDecryption(key, iv, cipherText []byte) ([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
blockMode := cipher.NewCBCDecrypter(block, iv)
origData := make([]byte, len(cipherText))
blockMode.CryptBlocks(origData, cipherText)
origData = PKCS5UnPadding(origData)
return origData, nil
}
func PKCS5Padding(src []byte, blockSize int) []byte {
padding := blockSize - len(src)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(src, padtext...)
}
func PKCS5UnPadding(src []byte) []byte {
length := len(src)
unpadding := int(src[length-1])
if length-unpadding > 0 {
return src[:(length - unpadding)]
} else {
return src
}
}
func base64Decode(str string) (string, bool) {
data, err := base64.StdEncoding.DecodeString(str)
if err != nil {
return "", true
}
return string(data), false
}
func jdkPBE_decipher_PBEWITHMD5andDES(password, src []byte) ([]byte, error) {
codedmsg, err := base64.StdEncoding.DecodeString(string(src))
if err != nil {
return codedmsg, err
}
// fmt.Printf("raw = % x\n", codedmsg)
salt := codedmsg[0:des.BlockSize]
msg := codedmsg[des.BlockSize:]
// fmt.Printf("salt = % x\n", salt)
// fmt.Printf("msg = % x\n", msg)
hasher := md5.New()
hasher.Write([]byte(password))
hasher.Write(salt) // Salt
result := hasher.Sum(nil)
for i := 0; i < 999; i++ {
hasher = md5.New()
hasher.Write(result)
result = hasher.Sum(nil)
}
// fmt.Printf("result = % x\n", result)
pass := result[0:des.BlockSize]
iv := result[des.BlockSize:]
// fmt.Printf("pass = % x\n", pass)
// fmt.Printf("iv = % x\n", iv)
res, err := DesDecryption(pass, iv, msg)
// fmt.Println(err)
// fmt.Println(string(res))
return res, err
}
func jdkPBE_cipher_PBEWITHMD5andDES(password, msg []byte) ([]byte, error) {
salt := make([]byte, des.BlockSize)
rand.Read(salt)
hasher := md5.New()
hasher.Write([]byte(password))
hasher.Write(salt) // Salt
result := hasher.Sum(nil)
for i := 0; i < 999; i++ {
hasher = md5.New()
hasher.Write(result)
result = hasher.Sum(nil)
}
// fmt.Printf("result = % x\n", result)
pass := result[0:des.BlockSize]
iv := result[des.BlockSize:]
// fmt.Printf("pass = % x\n", pass)
// fmt.Printf("iv = % x\n", iv)
res, err := DesEncryption(pass, iv, msg)
// fmt.Println(err)
// fmt.Println(string(res))
return []byte(base64.StdEncoding.EncodeToString(append(salt, res...))), err
}
func jdkPBE_decipher(ciphername string, password, src []byte) ([]byte, error) {
if ciphername == "PBEWITHMD5andDES" {
return jdkPBE_decipher_PBEWITHMD5andDES(password, src)
} else {
return nil, errors.New("unable to decode with ciphername " + ciphername)
}
}
func jdkPBE_cipher(ciphername string, password, src []byte) ([]byte, error) {
if ciphername == "PBEWITHMD5andDES" {
return jdkPBE_cipher_PBEWITHMD5andDES(password, src)
} else {
return nil, errors.New("unable to encode with ciphername " + ciphername)
}
}
func main() {
rand.Seed(time.Now().UnixNano())
args := os.Args
if len(args) < 5 {
fmt.Println("Args: operation ciphername password msg");
fmt.Println("Ex. to encrypt: e PBEWITHMD5andDES strangepassword \"uma mensagem\"");
fmt.Println("Ex. to decrypt: d PBEWITHMD5andDES strangepassword ZrpxVeCnVvbHGdWgGTtZdv6Jg+IMfbla");
os.Exit(1)
}
// ciphername := "PBEWITHMD5andDES"
ciphername := args[2]
//password := []byte("strangepassword")
password := []byte(args[3])
//src := []byte("ZrpxVeCnVvbHGdWgGTtZdv6Jg+IMfbla")
src := []byte(args[4])
if args[1] == "e" {
msg, err := jdkPBE_cipher(ciphername, password, src)
fmt.Println(err)
fmt.Println(string(msg))
} else if args[1] == "d" {
msg, err := jdkPBE_decipher(ciphername, password, src)
fmt.Println(err)
fmt.Println(string(msg))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment