-
-
Save charger/4b054f90fb9fa648177a9355418c4685 to your computer and use it in GitHub Desktop.
Example how encrypt/decrypt text with private GPG key using password stored in a file (to not store password in source code), and encode/decode with Base64Url.
This file contains hidden or 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" | |
"encoding/base64" | |
"fmt" | |
"golang.org/x/crypto/openpgp" | |
"golang.org/x/crypto/openpgp/armor" | |
"golang.org/x/crypto/openpgp/packet" | |
"io" | |
"io/ioutil" | |
"os" | |
"time" | |
) | |
const pubKey = "/path/to/public.asc" | |
const secretKey = "/path/to/secret.asc" | |
const passwdFileName = "/path/to/passphrase.txt" | |
//TODO: open keys once when starting app | |
func decodeAndDecryptWithTime(message []byte) ([]byte, float64, error) { | |
var st = time.Now() | |
bts, err := decodeAndDecrypt(message) | |
return bts, time.Now().Sub(st).Seconds(), err | |
} | |
func decodeAndDecrypt(encodedEncrypted []byte) ([]byte, error) { | |
//decrypt from Base64Url | |
var encryptedBytes []byte | |
encryptedBytes, err := base64.URLEncoding.DecodeString(string(encodedEncrypted)) | |
if err != nil { | |
return nil, err | |
} | |
// Read in public key | |
var entity2 *openpgp.Entity | |
var entitylist2 openpgp.EntityList | |
// read private key | |
keyringFileBuffer2, err := os.Open(secretKey) | |
if err != nil { | |
return nil, err | |
} | |
defer func() { | |
_ = keyringFileBuffer2.Close() | |
}() | |
entitylist2, err = openpgp.ReadArmoredKeyRing(keyringFileBuffer2) | |
if err != nil { | |
return nil, err | |
} | |
entity2 = entitylist2[0] | |
// Get the passphrase and read the open private key. | |
passwd, err := readPasswdFile(passwdFileName) | |
if err != nil { | |
return nil, err | |
} | |
err = entity2.PrivateKey.Decrypt(passwd) | |
if err != nil { | |
return nil, err | |
} | |
for _, subkey := range entity2.Subkeys { | |
err = subkey.PrivateKey.Decrypt(passwd) | |
if err != nil { | |
return nil, err | |
} | |
} | |
decryptedBytes, err := decrypt(entitylist2, encryptedBytes) | |
if err != nil { | |
return nil, err | |
} | |
return decryptedBytes, nil | |
} | |
func readPasswdFile(fileName string) ([]byte, error) { | |
passwd, err := ioutil.ReadFile(fileName) | |
if err != nil { | |
return nil, err | |
} | |
passwd = bytes.TrimRight(passwd, "\n") | |
return passwd, nil | |
} | |
func encryptAndEncodeWithTime(message []byte) ([]byte, float64, error) { | |
var st = time.Now() | |
bts, err := encryptAndEncode(message) | |
return bts, time.Now().Sub(st).Seconds(), err | |
} | |
func encryptAndEncode(message []byte) ([]byte, error) { | |
// Read in public key | |
recipient, err := readEntity(pubKey) | |
if err != nil { | |
return nil, err | |
} | |
// read private key | |
signer, err := readEntity(secretKey) | |
if err != nil { | |
return nil, err | |
} | |
passwd, err := readPasswdFile(passwdFileName) | |
if err != nil { | |
return nil, err | |
} | |
err = signer.PrivateKey.Decrypt(passwd) | |
if err != nil { | |
return nil, err | |
} | |
r := bytes.NewReader(message) | |
w := bytes.Buffer{} | |
err = encrypt([]*openpgp.Entity{recipient}, signer, r, &w) | |
if err != nil { | |
return nil, err | |
} | |
encoded := base64.URLEncoding.EncodeToString(w.Bytes()) | |
return []byte(encoded), nil | |
} | |
func readEntity(name string) (*openpgp.Entity, error) { | |
f, err := os.Open(name) | |
if err != nil { | |
return nil, err | |
} | |
defer func(f *os.File) { | |
err := f.Close() | |
if err != nil { | |
fmt.Printf("Error closing a file %s: %v", name, err) | |
} | |
}(f) | |
block, err := armor.Decode(f) | |
if err != nil { | |
return nil, err | |
} | |
return openpgp.ReadEntity(packet.NewReader(block.Body)) | |
} | |
func encrypt(recipients []*openpgp.Entity, signer *openpgp.Entity, r io.Reader, w io.Writer) error { | |
wc, err := openpgp.Encrypt(w, recipients, signer, &openpgp.FileHints{IsBinary: true}, nil) | |
if err != nil { | |
return err | |
} | |
if _, err := io.Copy(wc, r); err != nil { | |
return err | |
} | |
return wc.Close() | |
} | |
func decrypt(keyring openpgp.KeyRing, encrypted []byte) ([]byte, error) { | |
md, err := openpgp.ReadMessage(bytes.NewReader(encrypted), keyring, nil, nil) | |
if err != nil { | |
return nil, err | |
} | |
decryptedBytes, err := ioutil.ReadAll(md.UnverifiedBody) | |
if err != nil { | |
return nil, err | |
} | |
return decryptedBytes, nil | |
} |
hi @charger can you please give me any example to decrypt from sign and encrypted gpg file to plaintext?
currently i facing this issue right now
hi @charger can you please give me any example to decrypt from sign and encrypted gpg file to plaintext? currently i facing this issue right now
Sorry for late reply. I belive, you need use decodeAndDecrypt
. Path to keys provided as hardcode already so need to provide only array of bytes (your encrypted message), and receive array of bytes, which can be casted to string.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi @charger How do I encrypt and decrypt files?
Thanks.