Last active
August 30, 2024 05:58
-
-
Save stuart-warren/93750a142d3de4e8fdd2 to your computer and use it in GitHub Desktop.
golang gpg/openpgp encryption/decryption example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"code.google.com/p/go.crypto/openpgp" | |
"encoding/base64" | |
"io/ioutil" | |
"log" | |
"os" | |
) | |
// create gpg keys with | |
// $ gpg --gen-key | |
// ensure you correct paths and passphrase | |
const mySecretString = "this is so very secret!" | |
const prefix, passphrase = "/Users/stuart-warren/", "1234" | |
const secretKeyring = prefix + ".gnupg/secring.gpg" | |
const publicKeyring = prefix + ".gnupg/pubring.gpg" | |
func encTest(secretString string) (string, error) { | |
log.Println("Secret to hide:", secretString) | |
log.Println("Public Keyring:", publicKeyring) | |
// Read in public key | |
keyringFileBuffer, _ := os.Open(publicKeyring) | |
defer keyringFileBuffer.Close() | |
entityList, err := openpgp.ReadKeyRing(keyringFileBuffer) | |
if err != nil { | |
return "", err | |
} | |
// encrypt string | |
buf := new(bytes.Buffer) | |
w, err := openpgp.Encrypt(buf, entityList, nil, nil, nil) | |
if err != nil { | |
return "", err | |
} | |
_, err = w.Write([]byte(mySecretString)) | |
if err != nil { | |
return "", err | |
} | |
err = w.Close() | |
if err != nil { | |
return "", err | |
} | |
// Encode to base64 | |
bytes, err := ioutil.ReadAll(buf) | |
if err != nil { | |
return "", err | |
} | |
encStr := base64.StdEncoding.EncodeToString(bytes) | |
// Output encrypted/encoded string | |
log.Println("Encrypted Secret:", encStr) | |
return encStr, nil | |
} | |
func decTest(encString string) (string, error) { | |
log.Println("Secret Keyring:", secretKeyring) | |
log.Println("Passphrase:", passphrase) | |
// init some vars | |
var entity *openpgp.Entity | |
var entityList openpgp.EntityList | |
// Open the private key file | |
keyringFileBuffer, err := os.Open(secretKeyring) | |
if err != nil { | |
return "", err | |
} | |
defer keyringFileBuffer.Close() | |
entityList, err = openpgp.ReadKeyRing(keyringFileBuffer) | |
if err != nil { | |
return "", err | |
} | |
entity = entityList[0] | |
// Get the passphrase and read the private key. | |
// Have not touched the encrypted string yet | |
passphraseByte := []byte(passphrase) | |
log.Println("Decrypting private key using passphrase") | |
entity.PrivateKey.Decrypt(passphraseByte) | |
for _, subkey := range entity.Subkeys { | |
subkey.PrivateKey.Decrypt(passphraseByte) | |
} | |
log.Println("Finished decrypting private key using passphrase") | |
// Decode the base64 string | |
dec, err := base64.StdEncoding.DecodeString(encString) | |
if err != nil { | |
return "", err | |
} | |
// Decrypt it with the contents of the private key | |
md, err := openpgp.ReadMessage(bytes.NewBuffer(dec), entityList, nil, nil) | |
if err != nil { | |
return "", err | |
} | |
bytes, err := ioutil.ReadAll(md.UnverifiedBody) | |
if err != nil { | |
return "", err | |
} | |
decStr := string(bytes) | |
return decStr, nil | |
} | |
func main() { | |
encStr, err := encTest(mySecretString) | |
if err != nil { | |
log.Fatal(err) | |
} | |
decStr, err := decTest(encStr) | |
if err != nil { | |
log.Fatal(err) | |
} | |
// should be done | |
log.Println("Decrypted Secret:", decStr) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks, how about if I want to support dual keys?