2013-01-18 80 views
8

我想写一个实用程序,它使用RSA密钥对加密和解密纯文本文件。与往常一样,RSA密钥由ssh-keygen生成并存储在.ssh中。如何使用Go中的RSA密钥加密和解密纯文本?

我无法理解如何做,与Go语言的密码和加密/ RSA包?关于这些的文档有点稀疏(更加如此,因为我是加密的新手),并且只有很少的例子。我检查了rsa_test.go文件的任何线索,但它只是让我更困惑。

总之我试图加载从id_rsa和id_rsa.pub文件中的.ssh公钥/私钥对,并利用它们来加密/解密的纯文本文件。

预先感谢您!

+1

我想你可能会从包测试[这里]一些启发(HTTP ://golang.org/src/pkg/crypto/rsa/pkcs1v15_test.go)和/或[there](http://golang.org/src/pkg/crypto/rsa/rsa_test.go)。 – zzzz

+0

参见:http://unix.stackexchange.com/a/30074/22709和https://web.archive.org/web/20120124211352/http://blog.oddbit.com/2011/05/converting- openssh-public-keys.html –

回答

13

请记住,RSA的目的不是要成为一个分组密码。通常RSA用于加密一个对称密钥,然后用它来加密数据。考虑到这一点,但是,这里是可以使用RSA私钥到可以自行解密的数据进行加密的程序:

package main 

import (
    "crypto/rand" 
    "crypto/rsa" 
    "crypto/sha1" 
    "crypto/x509" 
    "encoding/pem" 
    "flag" 
    "io/ioutil" 
    "log" 
) 

// Command-line flags 
var (
    keyFile = flag.String("key", "id_rsa", "Path to RSA private key") 
    inFile = flag.String("in", "in.txt", "Path to input file") 
    outFile = flag.String("out", "out.txt", "Path to output file") 
    label = flag.String("label", "", "Label to use (filename by default)") 
    decrypt = flag.Bool("decrypt", false, "Decrypt instead of encrypting") 
) 

func main() { 
    flag.Parse() 

    // Read the input file 
    in, err := ioutil.ReadFile(*inFile) 
    if err != nil { 
     log.Fatalf("input file: %s", err) 
    } 

    // Read the private key 
    pemData, err := ioutil.ReadFile(*keyFile) 
    if err != nil { 
     log.Fatalf("read key file: %s", err) 
    } 

    // Extract the PEM-encoded data block 
    block, _ := pem.Decode(pemData) 
    if block == nil { 
     log.Fatalf("bad key data: %s", "not PEM-encoded") 
    } 
    if got, want := block.Type, "RSA PRIVATE KEY"; got != want { 
     log.Fatalf("unknown key type %q, want %q", got, want) 
    } 

    // Decode the RSA private key 
    priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) 
    if err != nil { 
     log.Fatalf("bad private key: %s", err) 
    } 

    var out []byte 
    if *decrypt { 
     if *label == "" { 
      *label = *outFile 
     } 
     // Decrypt the data 
     out, err = rsa.DecryptOAEP(sha1.New(), rand.Reader, priv, in, []byte(*label)) 
     if err != nil { 
      log.Fatalf("decrypt: %s", err) 
     } 
    } else { 
     if *label == "" { 
      *label = *inFile 
     } 
     out, err = rsa.EncryptOAEP(sha1.New(), rand.Reader, &priv.PublicKey, in, []byte(*label)) 
     if err != nil { 
      log.Fatalf("encrypt: %s", err) 
     } 
    } 

    // Write data to output file 
    if err := ioutil.WriteFile(*outFile, out, 0600); err != nil { 
     log.Fatalf("write output: %s", err) 
    } 
} 
+0

不应使用公钥进行加密? – Aliza

+0

@Aliza使用公钥完成加密。查看'if * decrypt'块的'else'子句 - 'EncryptOEAP'需要'&priv.PublicKey',它是公钥的一半。 –