|
|
@@ -0,0 +1,75 @@ |
|
|
package main |
|
|
|
|
|
import ( |
|
|
"crypto/aes" |
|
|
"crypto/cipher" |
|
|
"crypto/rand" |
|
|
"encoding/base64" |
|
|
"fmt" |
|
|
"io" |
|
|
) |
|
|
|
|
|
func main() { |
|
|
originalText := "encrypt this golang" |
|
|
fmt.Println(originalText) |
|
|
|
|
|
key := []byte("example key 1234") |
|
|
|
|
|
// encrypt value to base64 |
|
|
cryptoText := encrypt(key, originalText) |
|
|
fmt.Println(cryptoText) |
|
|
|
|
|
// encrypt base64 crypto to original value |
|
|
text := decrypt(key, cryptoText) |
|
|
fmt.Printf(text) |
|
|
} |
|
|
|
|
|
// encrypt string to base64 crypto using AES |
|
|
func encrypt(key []byte, text string) string { |
|
|
// key := []byte(keyText) |
|
|
plaintext := []byte(text) |
|
|
|
|
|
block, err := aes.NewCipher(key) |
|
|
if err != nil { |
|
|
panic(err) |
|
|
} |
|
|
|
|
|
// The IV needs to be unique, but not secure. Therefore it's common to |
|
|
// include it at the beginning of the ciphertext. |
|
|
ciphertext := make([]byte, aes.BlockSize+len(plaintext)) |
|
|
iv := ciphertext[:aes.BlockSize] |
|
|
if _, err := io.ReadFull(rand.Reader, iv); err != nil { |
|
|
panic(err) |
|
|
} |
|
|
|
|
|
stream := cipher.NewCFBEncrypter(block, iv) |
|
|
stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext) |
|
|
|
|
|
// convert to base64 |
|
|
return base64.StdEncoding.EncodeToString(ciphertext) |
|
|
} |
|
|
|
|
|
// decrypt from base64 to decrypted string |
|
|
func decrypt(key []byte, cryptoText string) string { |
|
|
ciphertext, _ := base64.StdEncoding.DecodeString(cryptoText) |
|
|
|
|
|
block, err := aes.NewCipher(key) |
|
|
if err != nil { |
|
|
panic(err) |
|
|
} |
|
|
|
|
|
// The IV needs to be unique, but not secure. Therefore it's common to |
|
|
// include it at the beginning of the ciphertext. |
|
|
if len(ciphertext) < aes.BlockSize { |
|
|
panic("ciphertext too short") |
|
|
} |
|
|
iv := ciphertext[:aes.BlockSize] |
|
|
ciphertext = ciphertext[aes.BlockSize:] |
|
|
|
|
|
stream := cipher.NewCFBDecrypter(block, iv) |
|
|
|
|
|
// XORKeyStream can work in-place if the two arguments are the same. |
|
|
stream.XORKeyStream(ciphertext, ciphertext) |
|
|
|
|
|
return fmt.Sprintf("%s", ciphertext) |
|
|
} |