Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to encrypt and decrypt plain text with a RSA keys in Go?

I am trying to write a utility program which encrypts and decrypts plain text files using a RSA key pair. The RSA keys were generated with ssh-keygen and are stored in .ssh, as usual.

I am having trouble understanding how to do that with the Go language crypto and crypto/rsa packages? The documentation on those is a little sparse (even more so because I am new to encryption) and there are very few examples. I checked the rsa_test.go file for any clues, but it only confused me more.

In short I am trying to load the public/private key pair from the id_rsa and id_rsa.pub files in .ssh and use them to encrypt/decrypt a plain text file.

Thank you in advance!

like image 435
Kiril Avatar asked Jan 18 '13 17:01

Kiril


People also ask

How do I decrypt RSA encrypted text?

As RSA is asymmetric encryption technique, if text is encrypted using public key then for decryption we should use the private key and vice versa. Select the Decryption Algorithm. Some Algorithms need to have key size greater than 512 bits. This should be the same algorithm you had used during encryption.

Can you encrypt with RSA public key?

RSA(Rivest-Shamir-Adleman) is an Asymmetric encryption technique that uses two different keys as public and private keys to perform the encryption and decryption. With RSA, you can encrypt sensitive information with a public key and a matching private key is used to decrypt the encrypted message.


1 Answers

Keep in mind that RSA is not designed to be a block cipher. Usually RSA is used to encrypt a symmetric key that is then used to encrypt the data. With that in mind, however, here is a program which can use an RSA private key to encrypt data that can be decrypted by itself:

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)
    }
}
like image 132
Kyle Lemons Avatar answered Sep 22 '22 05:09

Kyle Lemons