2017-08-28 100 views
1

我有一个使用gpg密钥并提示输入密码的应用程序。这是我做的方式,(基于一个例子,我在别处找到了:Golang pgp without secring

func Decrypt(publicKeyring string, secretKeyring string, key string, password string) (string, error) { 

    var entity *openpgp.Entity 
    var entityList openpgp.EntityList 

    keyringFileBuffer, err := os.Open(secretKeyring) 
    if err != nil { 
     return "", err 
    } 

    defer keyringFileBuffer.Close() 
    entityList, err = openpgp.ReadKeyRing(keyringFileBuffer) 
    if err != nil { 
     return "", err 
    } 
    entity = entityList[0] 

    passphraseByte := []byte(password) 
    entity.PrivateKey.Decrypt(passphraseByte) 
    for _, subkey := range entity.Subkeys { 
     subkey.PrivateKey.Decrypt(passphraseByte) 
    } 

    dec, err := base64.StdEncoding.DecodeString(key) 
    if err != nil { 
     return "", err 
    } 

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

    return decStr, nil 

} 

这里的假设是,用户具有传递一个KeyRin,并且它的默认值是secring,就像这样:

viper.SetDefault("gpgsecretkeyring", home+"/.gnupg/secring.gpg") 

然而,

我得到报告,在Mac上一些用户都在努力获取应用程序的工作,原因是他们不知道如何定义secring。

似乎GnuPG的较新版本已被弃用临时版。

https://www.gnupg.org/faq/whats-new-in-2.1.html#nosecring

我不知道如何阅读在这一点上使用golang.org/x/crypto/openpgp密钥。有没有这样做的最好方法的例子?

回答

0

我厌倦了这个,所以我决定从os.Exec掏出gpg -dq更容易。示例:

package gpg 

import (
    "bytes" 
    "encoding/base64" 
    "os/exec" 
) 

func Decrypt(key string) (string, error) { 

    var cmd exec.Cmd 
    var output bytes.Buffer 

    gpgCmd, err := exec.LookPath("gpg") 

    if err != nil { 
     return "", err 
    } 

    cmd.Path = gpgCmd 
    cmd.Args = []string{"--decrypt", "--quiet"} 

    dec, err := base64.StdEncoding.DecodeString(key) 
    if err != nil { 
     return "", err 
    } 

    // return the reader interface for dec (byte array) 
    d := bytes.NewReader(dec) 

    // pipe d to gpg commands stdin 
    cmd.Stdin = d 
    cmd.Stdout = &output 

    if err := cmd.Run(); err != nil { 
     return "", err 
    } 

    // return the output from the gpg command 
    return output.String(), nil 

} 
0

的GnuPG 2.1引入了两个变化:

  • 合并secring.gpgpubring.gpg文件,你应该能够从pubring.gpg文件中读取密钥。
  • 对于新的安装,使用新的密钥箱格式,这是go库不支持的(截至今日,至少)。旧的安装(因此,以旧格式的密钥环)不会自动合并。

如果你想使用GnuPG的钥匙环,直接调用GnuPG。如果你想使用Go的库,请不要混淆GnuPG的钥匙环文件并存储你自己的密钥副本。