2013-01-18 10 views
8

Ich versuche, ein Dienstprogramm zu schreiben, das Nur-Text-Dateien mit einem RSA-Schlüsselpaar verschlüsselt und entschlüsselt. Die RSA-Schlüssel wurden mit ssh-keygen generiert und wie üblich in .ssh gespeichert.Wie man einfachen Text mit einem RSA-Schlüssel in Go verschlüsseln und entschlüsseln kann?

Ich habe Probleme zu verstehen, wie man das mit den Go Language Crypto und Crypto/RSA-Paketen macht? Die Dokumentation dazu ist ein wenig spärlich (vor allem, weil ich neu in der Verschlüsselung bin) und es gibt sehr wenige Beispiele. Ich habe in der Datei rsa_test.go nach Hinweisen gesucht, aber das hat mich nur mehr verwirrt.

Kurz gesagt, ich versuche, das öffentliche/private Schlüsselpaar aus den Dateien id_rsa und id_rsa.pub in .ssh zu laden und sie zum Verschlüsseln/Entschlüsseln einer Nur-Text-Datei zu verwenden.

Vielen Dank im Voraus!

+1

Ich glaube, Sie könnten einige Anregungen aus dem Paket-Tests erhalten Sie [hier] (http : //golang.org/src/pkg/crypto/rsa/pkcs1v15_test.go) und/oder [dort] (http://golang.org/src/pkg/crypto/rsa/rsa_test.go). – zzzz

+0

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

Antwort

13

Beachten Sie, dass RSA nicht als Blockchiffre konzipiert ist. Normalerweise wird RSA verwendet, um einen symmetrischen Schlüssel zu verschlüsseln, der dann zum Verschlüsseln der Daten verwendet wird. Mit dem im Verstand, aber hier ist ein Programm, das einen privaten RSA-Schlüssel verwenden können, um Daten zu verschlüsseln, die von sich selbst entschlüsselt werden kann:

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

sollte keine Verschlüsselung mit dem öffentlichen Schlüssel vorgenommen werden? – Aliza

+0

@Aliza Die Verschlüsselung erfolgt mit dem öffentlichen Schlüssel. Siehe die "else" -Klausel des "if * decrypt" -Blocks - "EncryptOEAP" nimmt "& priv.PublicKey", was die öffentliche Hälfte des Schlüsselpaares ist. –