Last active
December 12, 2021 18:33
-
-
Save FZambia/f91ddffb1a2b776d56e1988c6048e4d8 to your computer and use it in GitHub Desktop.
Verify armored GPG signature using Go language
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" | |
"errors" | |
"fmt" | |
"io/ioutil" | |
"os" | |
"golang.org/x/crypto/openpgp/armor" | |
"golang.org/x/crypto/openpgp/packet" | |
) | |
var publicKey = `-----BEGIN PGP PUBLIC KEY BLOCK----- | |
Comment: GPGTools - https://gpgtools.org | |
mQENBFeXWTMBCAC++Yoc5IkDhWBHYOki7JaRCVwg++zWDP+hxoqEJhx1MjrDrSLH | |
AfmkagjmFY4phtXgDxnFx2MDgZ1ud8YV+YrRaOUQuKPjXlWCSG7CopqGGse+RvSk | |
3ic5ptqRBDyJ1qvHzCVNv/iMcaO1t7qmETBhkgIiBVRNiyaWi2bhqZvIQuyJn+0Y | |
LZEI9+ky4y07I4oMTZC2eFByTaAiiL4Xxg0U+MjCJyq4l+W0qJ8mfKJ8nh3NmgN7 | |
MmZL+Cr2SLYZXcrS3/WwMGtDuwNXcEoBNqKDZtXNZTmFvr7KuzpKfp/G1JFGCWRA | |
wr882hOY0bJQhaWhtXiP185rrDHNxJROk3ELABEBAAG0JUFsZXhhbmRyIEVtZWxp | |
biA8ZW1lbGluQGNvcnAubWFpbC5ydT6JATcEEwEKACEFAleXWTMCGwMFCwkIBwMF | |
FQoJCAsFFgIDAQACHgECF4AACgkQ2xG6dGflDRk2fAgAkB//zbcY5bSLVBtBBMXk | |
ezImoA6U4TX6Kp4+nuB2IXrDreQJGC55oxWuoKOyM6oTmSLRKr5O/U70869W+9Mc | |
cPeV95W0Fh9RVtdWDOWjgWoMud70+lftIpRPoHwC2pN/M1ehvR4cKSkODOp10KBa | |
PQk+7E079NW53HeL27WcOeG8XW7xacdOq/sF8t/0UNlCLVkv4DujQPjtCfqZuKex | |
XppXjogaGo9I/032oGZ2xejVHhgSldAKJrDsi3GmLgcFHQYJwVkihxXbWN5C8onp | |
bqxIjR0guP8/BrXFh5QuC4F3N0nwdb1UyLW4bSWXf/xmmB/Ul7tioFiB1P8D/vEu | |
77kBDQRXl1kzAQgAzGdeOGrIBA19CvWFSdAvr5fZMC9jVca1k21xsaD/AxoM+IXE | |
kg+I7AL/g5BtGG/7h+lJcxWvUVIw5ijClmokIIh6YgoolHitkS3SQN/DG+NadcNt | |
TmK15wlICr8M4ahr4RyeJLGMBRt6Ew21gJgVtaroDuFozSQT181/2nYNUrqg+fXY | |
1p8q06p5IIz4mVLHFJ0Q+w3KXOoIjj4Ekcfh03ttJaNCKgeXeHivZ2ypTxGd34lo | |
nQrw4c7NvPqZYPr+0alvakq/y7jteCjVrPxhV0M1+JDjjrKoBUCchuhVIco+Irr1 | |
J3CsHJjkx2h3QOdB+uFGZiSJAvtLq9TQA4MP8QARAQABiQEfBBgBCgAJBQJXl1kz | |
AhsMAAoJENsRunRn5Q0ZJMcH/RmNRH1w8cwHR+xsACU0Jp6vPPHyX0h6H3UZtJRg | |
qtDTL/K7R89LFdkGyp3qPraCSQGJfqKlaXjkrKaTNTHHQjDk6KTwl/ksWOkTY8Pc | |
iACS8wyroFntZX/2vd1Og6n7QY88gKXaEt04ZSue+z5rsqqIM7FeorB/3x8VhbLY | |
fqjPmKAhjOJ6LZY8kzar1SF2u4d2RvE3OuNIL+5DGTZQN7WEknnrc7DG7tChstij | |
FLNqzPVkYKNy/dkM0dqmbedmyNGW7gsJJiJP5/HNM5AuvxcvQLosevUiog0UczvJ | |
RU+3HpkK0754mIV/QrJg7Xb0pzkbtzhKMq3vwXmko4kAH2Q= | |
=G/wh | |
-----END PGP PUBLIC KEY BLOCK-----` | |
func checkSign(fileName, signatureFileName string) error { | |
fileContent, err := ioutil.ReadFile(fileName) | |
if err != nil { | |
return err | |
} | |
// Get a Reader for the signature file | |
sigFile, err := os.Open(signatureFileName) | |
if err != nil { | |
return err | |
} | |
defer func() { | |
if err := sigFile.Close(); err != nil { | |
panic(err) | |
} | |
}() | |
// Decode armored signature file | |
block, err := armor.Decode(sigFile) | |
if err != nil { | |
return fmt.Errorf("error decoding signature file: %s", err) | |
} | |
if block.Type != "PGP SIGNATURE" { | |
return errors.New("not an armored signature") | |
} | |
// Read signature body | |
pack, err := packet.Read(block.Body) | |
if err != nil { | |
return fmt.Errorf("error reading signature file: %s", err) | |
} | |
// Was it really a signature file ? If yes, get the Signature | |
signature, ok := pack.(*packet.Signature) | |
if !ok { | |
return errors.New("not a valid signature file") | |
} | |
// Decode armored public key | |
block, err = armor.Decode(bytes.NewReader([]byte(publicKey))) | |
if err != nil { | |
return fmt.Errorf("error decoding public key: %s", err) | |
} | |
if block.Type != "PGP PUBLIC KEY BLOCK" { | |
return errors.New("not an armored public key") | |
} | |
// Read the key | |
pack, err = packet.Read(block.Body) | |
if err != nil { | |
return fmt.Errorf("error reading public key: %s", err) | |
} | |
// Was it really a public key file ? If yes, get the PublicKey | |
publicKey, ok := pack.(*packet.PublicKey) | |
if !ok { | |
return errors.New("invalid public key") | |
} | |
// Get the hash method used for the signature | |
hash := signature.Hash.New() | |
// Hash the content of the file (if the file is big, that's where you have to change the code to avoid getting the whole file in memory, by reading and writting in small chunks) | |
_, err = hash.Write(fileContent) | |
if err != nil { | |
return err | |
} | |
// Check the signature | |
err = publicKey.VerifySignature(hash, signature) | |
if err != nil { | |
return err | |
} | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment