2

だから私は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)

明らかに私が理解していないことがあるので、助けていただければ幸いです。

4

2 に答える 2

7

セキュリティは非常に危険な領域であることを思い出してください.GoのOpenPGPパッケージが処理しているもの以上のトップレベルのタスクを、他の十分にテストされたコードに呼び出す方法がある場合は、それを検討してください. 少なくとも低レベルの詳細が外部委託されているのは良いことopenpgpです。それらは厄介で非常に間違いやすいためです。しかし、あらゆるレベルでの小さな間違いは、暗号化機能を役に立たなくするよりも悪化させる可能性があります。セキュリティ クリティカルではないコードを記述する方法があれば、それはセキュリティのために誰もができる最善の方法の 1 つです。

特定の質問について:Close()すべてをフラッシュするためにライターを使用する必要があります (OpenPGP のライターがcompress/gzip's などと共有する特性)。

無関係な変更: 物事を印刷する方法はより適切です。これにより、またはのような書式指定子を必要とするのではなくlog.Println、間にスペースを入れて印刷したい値の束を渡すことができます (たとえば、 Python のように) 。(最初の出力の「EXTRA」は、フォーマット指定子よりも多くのものを渡すときに Go が発行するものです。) エラーをチェックすることもベスト プラクティスです (必要があると思われる場所で s を削除しましたが、洗練されておらず、あまり考えずに、すべての呼び出しを取得できなかった可能性があります) 、コードで実行します。print"%s""%d"Printfif err != nilgo 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)
    }
}
于 2014-09-10T02:56:20.360 に答える
0

あなたのコードをテストすることはできませんが、考えられる唯一のことは、実行順序が間違っているということです。最初に文字列を作成し、次に Base64 にしてから暗号化します。ここで、Base64 を元に戻し、その後、エンコードされた文字列を復号化します。これらの最後の 2 つは交換する必要があります。

于 2014-09-08T00:49:31.253 に答える