Encryption openpgp golang gpg库的问题

Encryption openpgp golang gpg库的问题,encryption,go,public-key-encryption,gnupg,openpgp,Encryption,Go,Public Key Encryption,Gnupg,Openpgp,所以我对golang是个新手,我正在努力获得一个使用openpgp加密一些文本并再次解密的工作示例 以下是我目前的情况:() 这是基于 当我运行它时,它似乎部分工作,但只输出原始字符串的一些字符。。。更改原始字符串会导致一些非常奇怪的问题 2014/09/07 22:59:38 Secret: %!(EXTRA string=this is so very secret!) 2014/09/07 22:59:38 Secret Keyring: %!(EXTRA string=/Users/st

所以我对golang是个新手,我正在努力获得一个使用openpgp加密一些文本并再次解密的工作示例

以下是我目前的情况:()

这是基于

当我运行它时,它似乎部分工作,但只输出原始字符串的一些字符。。。更改原始字符串会导致一些非常奇怪的问题

2014/09/07 22:59:38 Secret: %!(EXTRA string=this is so very secret!)
2014/09/07 22:59:38 Secret Keyring: %!(EXTRA string=/Users/stuart-warren/.gnupg/secring.gpg)
2014/09/07 22:59:38 Public Keyring: %!(EXTRA string=/Users/stuart-warren/.gnupg/pubring.gpg)
2014/09/07 22:59:38 Passphrase: %!(EXTRA string=1234)
2014/09/07 22:59:38 Encrypted Secret: %!(EXTRA string=wcBMA5a76vUxixWPAQgAOkrt/LQ3u++VbJ/20egxCUzMqcMYtq+JXL7SqbB5S1KrgHhGd8RHUmxy2h45hOLcAt+kfvSz0EJ/EsCmwnbP6HRPEqiMLt6XaVS26Rr9HQHPpRBZkqnwAP0EmlYNnF5zjnU5xTcEOyyr7EYhEgDv0Ro1FQkaCL2xdBhDCXs4EdQsjVrcECWOt0KgbCWs+N/0cEdeyHwodkaDgJ7NMq/pPuviaRu4JHCIxMiyz8yhOCHOM+bI80KsJesjGrgbjnGDfJUZNYDBNc8PqzfC39lB2MBrn/w07thJxvjbep39R0u2C4eEcroTRLB+t9i4fJNiVpoSclYRSZXm5OsYYv/XwtLgAeRZ07lFEsGoHSbqGLUnHFFw4Svk4FPgCuGVpOCS4vYiisDg+ORYj8dpu/Z3gSlVJ6mhSr7H4J3i9vItRuBx4WUB4HHgmQ==)
2014/09/07 22:59:38 Decrypting private key using passphrase
2014/09/07 22:59:38 Finished decrypting private key using passphrase
2014/09/07 22:59:38 Decrypted Secret: %!(EXTRA string=this)

显然有一些我不理解的地方,因此我希望得到任何帮助。

我无法测试您的代码,但我唯一能想到的是,执行顺序是错误的。首先生成一个字符串,然后将其设为Base64,然后对其进行加密。现在撤消Base64,然后解密编码的字符串。最后两个必须被交换。

< P>提醒您,<强>安全是异常危险的领域<强>,并且如果有一个方法来调用其他经测试的代码,甚至比OpenGP软件包所处理的任务还要多,请考虑一下。最好至少将低级细节外包给
openpgp
,因为它们很糟糕,很容易出错。但任何级别的微小错误都可能使加密功能变得比无用更糟糕;如果有一种方法可以编写安全性较低的关键代码,那么这是任何人都可以为安全性做的最好的事情之一

关于具体问题:您必须
Close()
编写器才能将所有内容刷新(OpenPGP的编写器与
compress/gzip
共享一个特性)

不相关的更改:您打印东西的方式更适合
log.Println
,它只允许您传递一组要打印的值,这些值之间有空格(比如Python
print
),而不需要像
%s
%d
这样的格式说明符。(初始输出中的“额外”是Go的
Printf
在传递的内容超过了格式说明符时发出的信息。)检查错误也是最佳做法(我在需要的地方删除了
if err!=nil
s,但不雅观,也没有考虑太多,我可能没有得到所有的调用)要在代码上运行
go fmt

再一次,我无法证明此代码或类似代码的适航性。但现在它可以往返于所有文本。我最终得到了:

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() error {
    log.Println("Secret:", mysecretstring)
    log.Println("Secret Keyring:", secretKeyring)
    log.Println("Public Keyring:", publicKeyring)
    log.Println("Passphrase:", passphrase)

    // 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
    bytesp, err := ioutil.ReadAll(buf)
    if err != nil {
        return err
    }
    encstr := base64.StdEncoding.EncodeToString(bytesp)

    // Output encrypted/encoded string
    log.Println("Encrypted Secret:", encstr)

    // Here is where I would transfer the encrypted string to someone else
    // but we'll just decrypt it in the same code

    // init some vars
    var entity2 *openpgp.Entity
    var entitylist2 openpgp.EntityList

    // Open the private key file
    keyringFileBuffer2, err := os.Open(secretKeyring)
    if err != nil {
        return err
    }
    defer keyringFileBuffer2.Close()
    entitylist2, err = openpgp.ReadKeyRing(keyringFileBuffer2)
    if err != nil {
        return err
    }
    entity2 = entitylist2[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")
    entity2.PrivateKey.Decrypt(passphrasebyte)
    for _, subkey := range entity2.Subkeys {
        subkey.PrivateKey.Decrypt(passphrasebyte)
    }
    log.Println("Finished decrypting private key using passphrase")

    // Decode the base64 string
    dec, err := base64.StdEncoding.DecodeString(encstr)
    if err != nil {
        return err
    }

    // Decrypt it with the contents of the private key
    md, err := openpgp.ReadMessage(bytes.NewBuffer(dec), entitylist2, nil, nil)
    if err != nil {
        return err
    }
    bytess, err := ioutil.ReadAll(md.UnverifiedBody)
    if err != nil {
        return err
    }
    decstr := string(bytess)

    // should be done
    log.Println("Decrypted Secret:", decstr)

    return nil
}

func main() {
    err := encTest()
    if err != nil {
        log.Fatal(err)
    }
}

谢谢,你的建议听起来是个似是而非的错误。[愚蠢的评论编辑限制]然而:第32行将字符串加密为字节,第35行将字节编码为base64,第55行将base64解码为字节,第56行解密字节并转换回字符串。你是说这是错误的顺序?加密字符串后,从base64对其进行解码。这是一行:dec,:=base64.StdEncoding.DecodeString(encstr),在您的示例中,也不需要使用base64。若使用0-9和a-Z以及空格,当然不需要base64。也许这会让你更容易测试。稍后,您可以使用base64捕获所有内容。我已尝试通过将加密的字节数组Stright发送到解密部分而不做任何更改,从而从等式中删除base64。我认为问题不存在。我在代码中添加了更多的注释和赏金。我注意到Encrypt返回一个WriteCloser,而您从未关闭它。对于其他一些事情,如
compress/gzip
,我知道这可能会导致并非所有的输出都被刷新。(同时也是从所有方面检查
错误的最佳实践,即使是看起来不会出错的事情。)太棒了,你是个传奇人物。这已经困扰我好几天了!
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() error {
    log.Println("Secret:", mysecretstring)
    log.Println("Secret Keyring:", secretKeyring)
    log.Println("Public Keyring:", publicKeyring)
    log.Println("Passphrase:", passphrase)

    // 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
    bytesp, err := ioutil.ReadAll(buf)
    if err != nil {
        return err
    }
    encstr := base64.StdEncoding.EncodeToString(bytesp)

    // Output encrypted/encoded string
    log.Println("Encrypted Secret:", encstr)

    // Here is where I would transfer the encrypted string to someone else
    // but we'll just decrypt it in the same code

    // init some vars
    var entity2 *openpgp.Entity
    var entitylist2 openpgp.EntityList

    // Open the private key file
    keyringFileBuffer2, err := os.Open(secretKeyring)
    if err != nil {
        return err
    }
    defer keyringFileBuffer2.Close()
    entitylist2, err = openpgp.ReadKeyRing(keyringFileBuffer2)
    if err != nil {
        return err
    }
    entity2 = entitylist2[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")
    entity2.PrivateKey.Decrypt(passphrasebyte)
    for _, subkey := range entity2.Subkeys {
        subkey.PrivateKey.Decrypt(passphrasebyte)
    }
    log.Println("Finished decrypting private key using passphrase")

    // Decode the base64 string
    dec, err := base64.StdEncoding.DecodeString(encstr)
    if err != nil {
        return err
    }

    // Decrypt it with the contents of the private key
    md, err := openpgp.ReadMessage(bytes.NewBuffer(dec), entitylist2, nil, nil)
    if err != nil {
        return err
    }
    bytess, err := ioutil.ReadAll(md.UnverifiedBody)
    if err != nil {
        return err
    }
    decstr := string(bytess)

    // should be done
    log.Println("Decrypted Secret:", decstr)

    return nil
}

func main() {
    err := encTest()
    if err != nil {
        log.Fatal(err)
    }
}