openpgp golang gpg库的问题

时间:2014-09-07 22:21:18

标签: encryption go public-key-encryption gnupg openpgp

所以我对golang很陌生,我正努力想要用openpgp加密一些文本并再次解密它。

以下是我目前的情况:(https://gist.github.com/93750a142d3de4e8fdd2.git

package main

import (
    "log"
    "bytes"
    "code.google.com/p/go.crypto/openpgp"
    "encoding/base64"
    "io/ioutil"
    "os"
)

// create gpg keys with
// $ gpg --gen-key
// ensure you correct paths and passphrase

const mysecretstring = "this is so very secret!"
const secretKeyring = "/Users/stuart-warren/.gnupg/secring.gpg"
const publicKeyring = "/Users/stuart-warren/.gnupg/pubring.gpg"
const passphrase = "1234"

func main() {
    log.Printf("Secret: ", mysecretstring)
    log.Printf("Secret Keyring: ", secretKeyring)
    log.Printf("Public Keyring: ", publicKeyring)
    log.Printf("Passphrase: ", passphrase)

    // Read in public key
    keyringFileBuffer, _ := os.Open(publicKeyring)
    defer keyringFileBuffer.Close()
    entitylist, _ := openpgp.ReadKeyRing(keyringFileBuffer)

    // encrypt string
    buf := new(bytes.Buffer)
    w, _ := openpgp.Encrypt(buf, entitylist, nil, nil, nil)
    w.Write([]byte(mysecretstring))

    // Encode to base64
    bytesp, _ := ioutil.ReadAll(buf)
    encstr := base64.StdEncoding.EncodeToString(bytesp)

    // Output encrypted/encoded string
    log.Printf("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, _ := os.Open(secretKeyring)
    defer keyringFileBuffer2.Close()
    entitylist2, _ = openpgp.ReadKeyRing(keyringFileBuffer2)
    entity2 = entitylist2[0]

    // Get the passphrase and read the private key.
    // Have not touched the encrypted string yet
    passphrasebyte := []byte(passphrase)
    log.Printf("Decrypting private key using passphrase")
    entity2.PrivateKey.Decrypt(passphrasebyte)
    for _, subkey := range entity2.Subkeys {
            subkey.PrivateKey.Decrypt(passphrasebyte)
    }
    log.Printf("Finished decrypting private key using passphrase")

    // Decode the base64 string
    dec, _ := base64.StdEncoding.DecodeString(encstr)

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

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

}

这是基于https://github.com/jyap808/jaeger

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

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)

显然,我有一些不理解的东西,所以会感谢所给予的任何帮助。

2 个答案:

答案 0 :(得分:7)

提醒安全性是异常危险的领域,并且如果有方法可以调用其他经过良好测试的代码甚至更多的是您的顶级任务而不仅仅是Go的OpenPGP包裹正在为你处理,考虑一下。至少低级细节外包给openpgp是件好事,因为它们很讨厌,所以很容易出错。但是任何级别的微小错误都会使加密功能变得比无用更糟糕;如果有一种方法可以编写安全性较低的代码,那么这是任何人都可以为安全做的最好的事情之一。

关于具体问题:你必须Close()作者才能把所有东西都弄清楚(特权是OpenPGP'作者和compress/gzip分享的)。

无关的更改:您打印事物的方式更合适log.Println,它只是让您传递一堆您希望在其间打印空格的值(例如,Python {{1}而不是像print"%s"那样需要格式说明符。 (" EXTRA"在您的初始输出中,当您传递的内容比您的格式说明符更多时,Go "%d"会发出。)这也是检查的最佳做法错误(我放弃Printf s我看到需要的地方,但是没有太多考虑,而且没有太多考虑,我可能没有得到所有的调用)并且在你的代码上运行if err != nil

再次,我无法证明此代码的适航性或其他类似的东西。但现在它将所有文本往返。我结束了:

go fmt

答案 1 :(得分:0)

我无法测试你的代码,但我唯一可以想到的是,执行的顺序是错误的。首先创建一个字符串,然后将其设为Base64,然后加密它。现在撤消Base64,然后解密编码的字符串。必须交换最后两个。