Skip to content

Instantly share code, notes, and snippets.

@gilberto-009199
Created July 27, 2023 18:39
Show Gist options
  • Save gilberto-009199/077f3b969cc3258e4ffab10686d30204 to your computer and use it in GitHub Desktop.
Save gilberto-009199/077f3b969cc3258e4ffab10686d30204 to your computer and use it in GitHub Desktop.
Example of symmetric cryptography in Golang

Example of symmetric cryptography in Golang

Algoritm Symetric:

  • AES:
    • Segurança: 5
    • Eficiência: 5
    • Tamanho de Bloco: 128 bits (4)
  • 3DES:
    • Segurança: 3
    • Eficiência: 3
    • Tamanho de Bloco: 64 bits (2)
  • RC4:
    • Segurança: 1
    • Eficiência: 5
    • Tamanho de Bloco: Variável (1)
  • ChaCha20:
    • Segurança: 5
    • Eficiência: 5
    • Tamanho de Bloco: 512 bits (5)
  • Camellia:
    • Segurança: 4
    • Eficiência: 4
    • Tamanho de Bloco: 128 bits (4)
// You can edit this code!
// Click here and start typing.
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/des"
"crypto/rc4"
"fmt"
"github.com/aead/camellia"
"golang.org/x/crypto/chacha20"
)
func main() {
data := []byte("123456789123456789123456789")
key := []byte("123456789")
nonce := []byte("gil")
/* AES */
ciphertext, _ := encryptAES(data, key, nonce)
plaintext, _ := decryptAES(ciphertext, key, nonce)
fmt.Println("## AES ##")
fmt.Println("\tOrigin:\n\t", string(data))
fmt.Println("\tCipher:\n", string(ciphertext))
fmt.Println("\tPlain:\n\t", string(plaintext))
/**/
/* 3DES */
ciphertext, _ = encrypt3DES(data, key)
plaintext, _ = decrypt3DES(ciphertext, key)
fmt.Println("## 3DES ##")
fmt.Println("\tOrigin:\n\t", string(data))
fmt.Println("\tCipher:\n", string(ciphertext))
fmt.Println("\tPlain:\n\t", string(plaintext))
/**/
/* RC4 */
ciphertext = encryptRC4(data, key, nonce)
plaintext = decryptRC4(ciphertext, key, nonce)
fmt.Println("## RC4 ##")
fmt.Println("\tOrigin:\n\t", string(data))
fmt.Println("\tCipher:\n", string(ciphertext))
fmt.Println("\tPlain:\n\t", string(plaintext))
/**/
/* chacha20 */
ciphertext = encryptChaCha20(data, key, nonce)
plaintext = decryptChaCha20(ciphertext, key, nonce)
fmt.Println("## chacha20 ##")
fmt.Println("\tOrigin:\n\t", string(data))
fmt.Println("\tCipher:\n", string(ciphertext))
fmt.Println("\tPlain:\n\t", string(plaintext))
/**/
/* Camellia */
ciphertext, _ = encryptCamellia(data, key)
plaintext, _ = decryptCamellia(ciphertext, key)
fmt.Println("## Camellia ##")
fmt.Println("\tOrigin:\n\t", string(data))
fmt.Println("\tCipher:\n", string(ciphertext))
fmt.Println("\tPlain:\n\t", string(plaintext))
/**/
}
func encryptCamellia(data, key []byte) ([]byte, error) {
keyBuffer := key
lenKeyBuffer := len(keyBuffer)
if lenKeyBuffer < 32 {
complementBuffer := make([]byte, int(32-lenKeyBuffer))
keyBuffer = append(keyBuffer, complementBuffer...)
} else {
keyBuffer = keyBuffer[:32]
}
block, err := camellia.NewCipher(keyBuffer)
if err != nil {
return nil, err
}
ciphertext := make([]byte, camellia.BlockSize+len(data))
iv := ciphertext[:camellia.BlockSize]
cfb := cipher.NewCFBEncrypter(block, iv)
cfb.XORKeyStream(ciphertext[camellia.BlockSize:], data)
return ciphertext, nil
}
func decryptCamellia(data, key []byte) ([]byte, error) {
keyBuffer := key
lenKeyBuffer := len(keyBuffer)
if lenKeyBuffer < 32 {
complementBuffer := make([]byte, int(32-lenKeyBuffer))
keyBuffer = append(keyBuffer, complementBuffer...)
} else {
keyBuffer = keyBuffer[:32]
}
block, err := camellia.NewCipher(keyBuffer)
if err != nil {
return nil, err
}
plaintext := make([]byte, camellia.BlockSize+len(data))
iv := plaintext[:camellia.BlockSize]
cfb := cipher.NewCFBDecrypter(block, iv)
cfb.XORKeyStream(plaintext[camellia.BlockSize:], data)
return plaintext[camellia.BlockSize*2:], nil
}
// ChaCha20
func encryptChaCha20(data, key, nonce []byte) []byte {
keyBuffer := key
lenKeyBuffer := len(keyBuffer)
if lenKeyBuffer < chacha20.KeySize {
complementBuffer := make([]byte, int(chacha20.KeySize-lenKeyBuffer))
keyBuffer = append(keyBuffer, complementBuffer...)
} else {
keyBuffer = keyBuffer[:chacha20.KeySize]
}
nonceBuffer := nonce
lenNonceBuffer := len(nonceBuffer)
if lenNonceBuffer < 24 {
complementBuffer := make([]byte, int(24-lenNonceBuffer))
nonceBuffer = append(nonceBuffer, complementBuffer...)
} else {
nonceBuffer = nonceBuffer[:24]
}
cipher, e := chacha20.NewUnauthenticatedCipher(keyBuffer, nonceBuffer)
if e != nil {
fmt.Println(e)
}
ciphertext := make([]byte, len(data))
cipher.XORKeyStream(ciphertext, data)
return ciphertext
}
func decryptChaCha20(ciphertext, key, nonce []byte) []byte {
keyBuffer := key
lenKeyBuffer := len(keyBuffer)
if lenKeyBuffer < chacha20.KeySize {
complementBuffer := make([]byte, int(chacha20.KeySize-lenKeyBuffer))
keyBuffer = append(keyBuffer, complementBuffer...)
} else {
keyBuffer = keyBuffer[:chacha20.KeySize]
}
nonceBuffer := nonce
lenNonceBuffer := len(nonceBuffer)
if lenNonceBuffer < 24 {
complementBuffer := make([]byte, int(24-lenNonceBuffer))
nonceBuffer = append(nonceBuffer, complementBuffer...)
} else {
nonceBuffer = nonceBuffer[:24]
}
cipher, e := chacha20.NewUnauthenticatedCipher(keyBuffer, nonceBuffer)
if e != nil {
fmt.Println(e)
}
plaintext := make([]byte, len(ciphertext))
cipher.XORKeyStream(plaintext, ciphertext)
return plaintext
}
// RC4 is Insecure
func encryptRC4(data, key, salt []byte) []byte {
cipher, _ := rc4.NewCipher(append(key, salt...))
ciphertext := make([]byte, len(data))
cipher.XORKeyStream(ciphertext, data)
return ciphertext
}
func decryptRC4(data, key, nonce []byte) []byte {
cipher, _ := rc4.NewCipher(append(key, nonce...))
plaintext := make([]byte, len(data))
cipher.XORKeyStream(plaintext, data)
return plaintext
}
// 3DES (Triple DES) NOT USE NONCE
func encrypt3DES(data, key []byte) ([]byte, error) {
keyBuffer := key
lenKeyBuffer := len(keyBuffer)
if lenKeyBuffer < 24 {
complementBuffer := make([]byte, int(24-lenKeyBuffer))
keyBuffer = append(keyBuffer, complementBuffer...)
} else {
keyBuffer = keyBuffer[:24]
}
block, e := des.NewTripleDESCipher(keyBuffer)
if e != nil {
fmt.Println(e)
return nil, e
}
ciphertext := make([]byte, des.BlockSize+len(data))
iv := ciphertext[:des.BlockSize]
cfb := cipher.NewCFBEncrypter(block, iv)
cfb.XORKeyStream(ciphertext[des.BlockSize:], data)
return ciphertext, nil
}
func decrypt3DES(data, key []byte) ([]byte, error) {
keyBuffer := key
lenKeyBuffer := len(keyBuffer)
if lenKeyBuffer < 24 {
complementBuffer := make([]byte, int(24-lenKeyBuffer))
keyBuffer = append(keyBuffer, complementBuffer...)
} else {
keyBuffer = keyBuffer[:24]
}
block, e := des.NewTripleDESCipher(keyBuffer)
if e != nil {
fmt.Println(e)
return nil, e
}
ciphertext := make([]byte, des.BlockSize+len(data))
iv := ciphertext[:des.BlockSize]
cfb := cipher.NewCFBDecrypter(block, iv)
cfb.XORKeyStream(ciphertext[des.BlockSize:], data)
return ciphertext[des.BlockSize+des.BlockSize:], nil
}
// AES (Advanced Encryption Standard)
func encryptAES(data, key []byte, nonce []byte) ([]byte, error) {
keyBuffer := key
lenKeyBuffer := len(keyBuffer)
if lenKeyBuffer < 32 {
complementBuffer := make([]byte, int(32-lenKeyBuffer))
keyBuffer = append(keyBuffer, complementBuffer...)
} else {
keyBuffer = keyBuffer[:32]
}
nonceBuffer := nonce
lenNonceBuffer := len(nonceBuffer)
if lenNonceBuffer < 12 {
complementBuffer := make([]byte, int(12-lenNonceBuffer))
nonceBuffer = append(nonceBuffer, complementBuffer...)
} else {
nonceBuffer = nonceBuffer[:12]
}
block, e := aes.NewCipher(keyBuffer)
if e != nil {
fmt.Println(e)
return nil, e
}
gcm, e := cipher.NewGCM(block)
if e != nil {
fmt.Println(e)
return nil, e
}
ciphertext := gcm.Seal(nil, nonceBuffer, data, nil)
return ciphertext, nil
}
func decryptAES(ciphertext, key []byte, nonce []byte) ([]byte, error) {
keyBuffer := key
lenKeyBuffer := len(keyBuffer)
if lenKeyBuffer < 32 {
complementBuffer := make([]byte, int(32-lenKeyBuffer))
keyBuffer = append(keyBuffer, complementBuffer...)
} else {
keyBuffer = keyBuffer[:32]
}
nonceBuffer := nonce
lenNonceBuffer := len(nonceBuffer)
if lenNonceBuffer < 12 {
complementBuffer := make([]byte, int(12-lenNonceBuffer))
nonceBuffer = append(nonceBuffer, complementBuffer...)
} else {
nonceBuffer = nonceBuffer[:12]
}
block, e := aes.NewCipher(keyBuffer)
if e != nil {
fmt.Println(e)
return nil, e
}
gcm, e := cipher.NewGCM(block)
if e != nil {
fmt.Println(e)
return nil, e
}
plaintext, e := gcm.Open(nil, nonceBuffer, ciphertext, nil)
if e != nil {
fmt.Println(e)
return nil, e
}
return plaintext, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment