-
-
Save stuart-warren/93750a142d3de4e8fdd2 to your computer and use it in GitHub Desktop.
| 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) | |
| } |
I believe the url has changed for the openpgp package to golang.org/x/crypto/openpgp
Awesome code snippet! Only comment was for anyone referencing this code to decrypt something other than a string, such as a big encrypted file. It would be safer and might save you a ton of time debugging if you read in the decrypted string using _, err := ioutil.copy(decryptWriter, md.UnverifiedBody) instead of bytes, err := ioutil.ReadAll(md.UnverifiedBody)
Thanks, this gist works! I had struggled a bit with generation of secring.gpg and pubring.gpg, though.
To generate throwaway keys for experiments, following commands can be used generate a new key in .gnupg as subdirectory of the current directory, and .gnupg/secring.gpg and .gnupg/pubring.gpg keyrings:
gpg --gen-key --homedir .gnupg
gpg --no-default-keyring --homedir ./.gnupg/ --export-secret-keys > ./.gnupg/secring.gpg
gpg --no-default-keyring --homedir ./.gnupg/ --export > ./.gnupg/pubring.gpgThanks, how about if I want to support dual keys?
thanks mates, now it finally works for me too..
If you have created your keyring with gnupg >=v2 you need to export the secret keys e.g. with
🤦♂️