package aes import ( caes "crypto/aes" "crypto/cipher" "crypto/hmac" "crypto/rand" "crypto/sha256" b64 "encoding/base64" "encoding/hex" "errors" "fmt" "strings" log "github.com/rs/zerolog/log" ) type AesKey struct { KeyHex string `json:"key_string" eru:"required"` Key []byte `json:"key" eru:"required"` Bits int `json:"bits" eru:"required"` } type ecb struct { block cipher.Block blockSize int } func newECB(block cipher.Block) *ecb { return &ecb{ block: block, blockSize: block.BlockSize(), } } type ecbEncrypter ecb func NewECBEncrypter(block cipher.Block) cipher.BlockMode { return (*ecbEncrypter)(newECB(block)) } func (e *ecbEncrypter) BlockSize() int { return e.blockSize } func (e *ecbEncrypter) CryptBlocks(dst, src []byte) { if len(src)%e.blockSize != 0 { panic("crypto/cipher: input blocks are not full") } if len(dst) < len(src) { panic("crypto/cipher: output is smaller than input") } for len(src) > 0 { e.block.Encrypt(dst, src[:e.blockSize]) src = src[e.blockSize:] dst = dst[e.blockSize:] } } type ecbDecrypter ecb func NewECBDecrypter(block cipher.Block) cipher.BlockMode { return (*ecbDecrypter)(newECB(block)) } func (d *ecbDecrypter) BlockSize() int { return d.blockSize } func (d *ecbDecrypter) CryptBlocks(dst, src []byte) { log.Print("len(src) = ", len(src)) log.Print("d.blockSize = ", d.blockSize) if len(src)%d.blockSize != 0 { panic("crypto/cipher: input blocks are not full") } if len(dst) < len(src) { panic("crypto/cipher: output is smaller than input") } for len(src) > 0 { d.block.Decrypt(dst, src[:d.blockSize]) src = src[d.blockSize:] dst = dst[d.blockSize:] } } func GenerateKey(bits int) (aesKey AesKey, err error) { log.Print("inside GenerateKey") aesKey.Bits = bits bytes := make([]byte, bits/8) //generate a random xx byte key for AES-256 if _, err := rand.Read(bytes); err != nil { log.Print(err.Error()) } aesKey.KeyHex = hex.EncodeToString(bytes) aesKey.Key = bytes log.Print(bytes) log.Print(string(bytes)) return } func EncryptECB(plainBytes []byte, aesKey []byte) (encryptedBytes []byte, err error) { block, err := caes.NewCipher(aesKey) if err != nil { log.Print(err.Error()) return } log.Print("len(plainBytes) = ", len(plainBytes)) log.Print(fmt.Sprint(plainBytes)) plaintext := Pad(plainBytes, block.BlockSize()) log.Print("len(plaintext) = ", len(plaintext)) log.Print(string(plaintext)) ecbObj := NewECBEncrypter(block) encryptedBytes = make([]byte, len(plaintext)) ecbObj.CryptBlocks(encryptedBytes, plaintext) log.Print("len(encryptedBytes) = ", len(encryptedBytes)) log.Print("len(plaintext) = ", len(plaintext)) /*ecbdObj := NewECBDecrypter(block) plainBytesBeforeUnpad := make([]byte,len(encryptedBytes)) log.Print("len(plainBytesBeforeUnpad) = ",len(plainBytesBeforeUnpad)) ecbdObj.CryptBlocks(plainBytesBeforeUnpad,encryptedBytes) plainBytes, err = Unpad(plainBytesBeforeUnpad) if err != nil { log.Print(err.Error()) return } log.Print(string(plainBytes)) */ return encryptedBytes, err } func DecryptECB(encryptedBytes []byte, aesKey []byte) (plainBytes []byte, err error) { log.Print("len(encryptedBytes) = ", len(encryptedBytes)) block, err := caes.NewCipher(aesKey) if err != nil { log.Print(err.Error()) return } ecbdObj := NewECBDecrypter(block) plainBytesBeforeUnpad := make([]byte, len(encryptedBytes)) log.Print("len(plainBytesBeforeUnpad) = ", len(plainBytesBeforeUnpad)) ecbdObj.CryptBlocks(plainBytesBeforeUnpad, encryptedBytes) plainBytes, err = Unpad(plainBytesBeforeUnpad) if err != nil { log.Print(err.Error()) return } return plainBytes, err } func EncryptCBC(plainText string, encKey string, iv string) (encryptedString string) { bKey := []byte(encKey) bIV := []byte(iv) //cipherTextDecoded, err := hex.DecodeString(cipherText) //if err != nil { // panic(err) //} block, err := caes.NewCipher(bKey) if err != nil { panic(err) } log.Print("block size = ", block.BlockSize()) //paddding with spaces //if block.BlockSize() < 1 || block.BlockSize() > 255 { // panic(fmt.Sprintf("inappropriate block size %d", block.BlockSize())) //} //plainBuf := []byte(plainText) //i := block.BlockSize() - (len(plainBuf) % block.BlockSize()) //spaceByte := []byte(" ") //finalPlainBytes := append(plainBuf, bytes.Repeat(spaceByte, i)...) //finalPlainText := string(finalPlainBytes) //paddding with spaces ended bCipherText := make([]byte, len(plainText)) mode := cipher.NewCBCEncrypter(block, bIV) mode.CryptBlocks(bCipherText, []byte(plainText)) return string(bCipherText) } func DecryptCBC(cipherText string, encKey string, iv string) (decryptedString string) { bKey := []byte(encKey) bIV := []byte(iv) //cipherTextDecoded, err := hex.DecodeString(cipherText) //if err != nil { // panic(err) //} block, err := caes.NewCipher(bKey) if err != nil { panic(err) } bPlaintext := make([]byte, len(cipherText)) mode := cipher.NewCBCDecrypter(block, bIV) mode.CryptBlocks([]byte(bPlaintext), []byte(cipherText)) return strings.Trim(string(bPlaintext), " ") } /*func EncryptCBC(plainText string, encKey string, iv string) (encryptedString string) { bKey := []byte(encKey) bIV := []byte(iv) //cipherTextDecoded, err := hex.DecodeString(cipherText) //if err != nil { // panic(err) //} block, err := caes.NewCipher(bKey) if err != nil { panic(err) } log.Print("block..BlockSize() = ",block.BlockSize()) bCipherText := make([]byte, len(plainText)) mode := cipher.NewCBCEncrypter(block, bIV) mode.CryptBlocks([]byte(bCipherText), []byte(plainText)) log.Print(bCipherText) log.Print(string(bCipherText)) return string(bCipherText) } func DecryptCBC(cipherText string, encKey string, iv string) (decryptedString string) { bKey := []byte(encKey) bIV := []byte(iv) //cipherTextDecoded, err := hex.DecodeString(cipherText) //if err != nil { // panic(err) //} block, err := caes.NewCipher(bKey) if err != nil { panic(err) } bPlaintext := make([]byte, len(cipherText)) mode := cipher.NewCBCDecrypter(block, bIV) mode.CryptBlocks([]byte(bPlaintext), []byte(cipherText)) return strings.Trim(string(bPlaintext), " ") } */ func Encrypt(plainBytes []byte, aesKeyStr string) (encryptedBytes []byte, err error) { log.Print("aesKeyStr = ", aesKeyStr) //key, err := hex.DecodeString(aesKeyStr) //log.Print("error from hex.DecodeString(aesKeyStr) ", err.Error()) //log.Print(key) key := []byte(aesKeyStr) block, err := caes.NewCipher(key) if err != nil { log.Print("error from caes.NewCipher(key)") log.Print(err.Error()) return } aesGCM, err := cipher.NewGCM(block) if err != nil { log.Print(err.Error()) return } nonce := make([]byte, aesGCM.NonceSize()) encryptedBytes = aesGCM.Seal(nonce, nonce, plainBytes, nil) return } func Decrypt(encryptedBytes []byte, aesKeyStr string) (decryptedBytes []byte, err error) { key, _ := hex.DecodeString(aesKeyStr) log.Print(key) //enc, err := hex.DecodeString(string(encryptedBytes)) if err != nil { log.Print(err.Error()) return } //Create a new Cipher Block from the key block, err := caes.NewCipher(key) if err != nil { log.Print(err.Error()) return } //Create a new GCM aesGCM, err := cipher.NewGCM(block) if err != nil { log.Print(err.Error()) return } //Get the nonce size nonceSize := aesGCM.NonceSize() log.Print("len(encryptedBytes) = ", len(encryptedBytes)) if len(encryptedBytes) < nonceSize { err = errors.New("length of encryptedBytes is less then nonce size") log.Error().Err(err).Msg(err.Error()) return } log.Print("nonceSize = ", nonceSize) //Extract the nonce from the encrypted data nonce, ciphertext := encryptedBytes[:nonceSize], encryptedBytes[nonceSize:] //Decrypt the data decryptedBytes, err = aesGCM.Open(nil, nonce, ciphertext, nil) if err != nil { log.Print(err.Error()) return } return } func EncryptData(plainTextBeforePadding string) string { org_aes_key := "CRDRIAF" aes_key := fmt.Sprint(org_aes_key, strings.Repeat("\000", 9)) //aes_key := fmt.Sprint("CRDRIAF", strings.Repeat((" "), 9)) iv := "lksdasfsaskllopl" //plainTextBeforePadding := "544458556955" plainTextBytes := Pad([]byte(plainTextBeforePadding), 16) plainText := string(plainTextBytes) log.Print("plaintext after padding = ", plainText) encryptedString := EncryptCBC(plainText, aes_key, iv) log.Print("encryptedString") log.Print(encryptedString) log.Print(len(encryptedString)) encryptedStringb64 := b64.StdEncoding.EncodeToString([]byte(encryptedString)) log.Print(encryptedStringb64) hash_map := string(Hmac([]byte(encryptedString), org_aes_key)) log.Print("hash_map") log.Print(hash_map) log.Print(len(hash_map)) encodedFinalValue := b64.StdEncoding.EncodeToString([]byte(fmt.Sprint(iv, hash_map, encryptedString))) log.Print(encodedFinalValue) return encodedFinalValue } func DecryptData(encodedFinalValue string) string { org_aes_key := "CRDRIAF" aes_key := fmt.Sprint(org_aes_key, strings.Repeat("\000", 9)) //aes_key := fmt.Sprint("CRDRIAF", strings.Repeat((" "), 9)) iv := "lksdasfsaskllopl" //encodedFinalValue = "bGtzZGFzZnNhc2tsbG9wbFj8fhIBfHrYNgJky65TCDz3rnCsQpzHoCrVyBSR4EDBnOrs11yqmCQYTDqP+Z5PsA==" //checking with actual decryption process encryptedBytes, err := b64.StdEncoding.DecodeString(encodedFinalValue) if err != nil { log.Error().Err(err).Msg(err.Error()) } encyptedStr := string(encryptedBytes) log.Print(len(encyptedStr)) log.Print(encyptedStr) actualEncyptedStr := encyptedStr[48:len(encyptedStr)] log.Print(actualEncyptedStr) decryptedFinalString := DecryptCBC(actualEncyptedStr, aes_key, iv) log.Print("decryptedFinalString") decryptedFinalStringUnpadded, err := Unpad([]byte(decryptedFinalString)) log.Print(err) log.Print(string(decryptedFinalStringUnpadded)) return string(decryptedFinalStringUnpadded) } func NewSHA256(data []byte) []byte { hash := sha256.Sum256(data) //log.Print(string(hash[:])) return hash[:] } func Hmac(data []byte, secret string) []byte { h := hmac.New(sha256.New, []byte(secret)) h.Write([]byte(data)) return h.Sum(nil) }