failure in go.crypto and GnuPG interoperability
Casey Marshall
casey.marshall at gmail.com
Thu Jan 30 18:28:13 CET 2014
go.crypto is interpreting the plaintext input as text and mangling it,
as the input is binary. If you encrypt with:
cWrt, err := openpgp.Encrypt(cBuf, ents, nil,
&openpgp.FileHints{IsBinary: true}, nil)
you should see output identical to the input.
-Casey
On 01/30/2014 06:30 AM, Bernd Fix wrote:
> I am working on an application that is encrypting content with the
> openpgp functions from the go.crypto framework. This content is later to
> be decrypted using the GnuPG application on a Linux box. There seems to
> be an incompatibility between go.crypto and the GnuPG that fails to
> decrypt the original content correctly - the decrypted content for
> larger files is smaller than the original input.
>
> I am using Debian7 with the tip version of Go, the current go.crypto
> repository and GnuPG 1.4.12. The following steps will reproduce the problem:
>
> (1) create a file with random content (1MB in this case):
>
> dd if=/dev/urandom of=xxx.in count=2048
>
> (2) create a local keyring for testing:
>
> gpg --home . --gen-key
>
> I used RSA-4096 keys and "testtest" as a password; if you use a
> different password, change the source code of the test app; create only
> one key in the keyring!
>
> (3) compile the test app from the source code below:
>
> go build test.go
>
> (4) Run the test app:
>
> ./test
>
> The output "Compare: 0" indicates that the encryption/decryption cycle
> in go.crypto worked fine and delivered the expected result.
>
> (5) Decrypt output using GnuPG:
>
> gpg --home . -o xxx.out -d xxx.in.gpg
>
> Compare the two files; you will see something like:
>
> -rw-r--r-- 1 test test 1048576 Jan 30 13:06 xxx.in
> -rw-r--r-- 1 test test 1044505 Jan 30 13:18 xxx.out
>
>
> The two files don't match and neither the test app nor GnuPG showed any
> warning or error message. Am I doing something wrong or what is going on
> here?
>
> Regards, Bernd.
>
> =====[test.go]=================================================
>
> package main
>
> import (
> "bytes"
> "code.google.com/p/go.crypto/openpgp"
> "fmt"
> "io"
> "io/ioutil"
> "os"
> )
>
> const (
> FILE = "xxx.in"
> GNUPG = "secring.gpg"
> PASSP = "testtest"
> )
>
> func main() {
> rdr, err := os.Open(GNUPG)
> if err != nil {
> panic(err.Error())
> }
> defer rdr.Close()
> ents, err := openpgp.ReadKeyRing(rdr)
> if err != nil {
> panic(err.Error())
> }
>
> f, err := os.Open(FILE)
> if err != nil {
> panic(err.Error())
> }
> plain, err := ioutil.ReadAll(f)
> if err != nil {
> panic(err.Error())
> }
>
> cBuf := new(bytes.Buffer)
> cWrt, err := openpgp.Encrypt(cBuf, ents, nil, nil, nil)
> if err != nil {
> panic(err.Error())
> }
> cWrt.Write(plain)
> cWrt.Close()
> cipher := cBuf.Bytes()
>
> out, err := os.Create(FILE + ".gpg")
> if err != nil {
> panic(err.Error())
> }
> out.Write(cipher)
> out.Close()
>
> cBuf = bytes.NewBuffer(cipher)
> pBuf := new(bytes.Buffer)
> md, err := openpgp.ReadMessage(
> cBuf,
> ents,
> func(keys []openpgp.Key, symmetric bool) ([]byte, error) {
> priv := keys[0].PrivateKey
> if priv.Encrypted {
> priv.Decrypt([]byte(PASSP))
> }
> buf := new(bytes.Buffer)
> priv.Serialize(buf)
> return buf.Bytes(), nil
> },
> nil)
> if err != nil {
> panic(err.Error())
> }
> buf := make([]byte, 1024)
> for {
> n, err := md.UnverifiedBody.Read(buf)
> pBuf.Write(buf[:n])
> if err != nil {
> if err == io.EOF {
> err = nil
> break
> }
> panic(err.Error())
> }
> }
> plain2 := pBuf.Bytes()
> fmt.Printf("Compare: %d\n", bytes.Compare(plain, plain2))
> }
>
>
>
>
> _______________________________________________
> Gnupg-devel mailing list
> Gnupg-devel at gnupg.org
> http://lists.gnupg.org/mailman/listinfo/gnupg-devel
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: </pipermail/attachments/20140130/5db7c564/attachment-0001.sig>
More information about the Gnupg-devel
mailing list