2013-01-18 10 views
8

Próbuję napisać program narzędziowy, który szyfruje i odszyfrowuje pliki tekstowe przy użyciu pary kluczy RSA. Klucze RSA zostały wygenerowane za pomocą ssh-keygen i są przechowywane jak zwykle w .ssh.Jak szyfrować i odszyfrowywać zwykły tekst za pomocą kluczy RSA w programie Go?

Mam problem ze zrozumieniem, jak to zrobić z pakietami crypto i crypto/rsa języka Go? Dokumentacja na nich jest trochę skąpa (tym bardziej, że jestem nowy w szyfrowaniu) i jest bardzo mało przykładów. Sprawdziłem plik rsa_test.go w poszukiwaniu jakichkolwiek wskazówek, ale tylko mnie to bardziej zdezorientowało.

W skrócie próbuję załadować parę kluczy publiczny/prywatny z plików id_rsa i id_rsa.pub do pliku .ssh i użyć ich do zaszyfrowania/odszyfrowania pliku tekstowego.

Z góry dziękuję!

+1

myślę można zaczerpnąć inspirację z testów paczce [tutaj] (http : //golang.org/src/pkg/crypto/rsa/pkcs1v15_test.go) i/lub [tam] (http://golang.org/src/pkg/crypto/rsa/rsa_test.go). – zzzz

+0

Zobacz także: http://unix.stackexchange.com/a/30074/22709 i https://web.archive.org/web/20120124211352/http://blog.oddbit.com/2011/05/converting- openssh-public-keys.html –

Odpowiedz

13

Należy pamiętać, że RSA nie zostało zaprojektowane jako szyfr blokowy. Zwykle RSA służy do szyfrowania klucza symetrycznego, który jest następnie używany do szyfrowania danych. Mając to na uwadze, jednak tutaj to program, który można używać klucza prywatnego RSA do szyfrowania danych, które można odszyfrować sam:

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

nie należy szyfrować za pomocą klucza publicznego? – Aliza

+0

@Aliza Szyfrowanie odbywa się za pomocą klucza publicznego. Zobacz klauzulę 'else' bloku' if * decrypt' - 'EncryptOEAP' pobiera' & priv.PublicKey', która jest publiczną połówką keypair. –