RSA To “Go” …

The method described in this article is here.

RSA To “Go” …

The method described in this article is here.

The RSA method was published in August 1977, and it is still going strong. While it can be slow — and where Shor illustrated that the 768-bit version can be easily cracked by quantum computes — it still exists within our PKI world, and also within secure email systems. So let’s use the Go programming language, and encrypt and decrypt a simple message.

RSA uses a public key and a private key, and where we can encrypt with the public key and decrypt with the private key. In this case Alice will send an encrypted message to Bob, so Alice needs to use Bob’s public key to encrypt the message, and then he will use his private key to decrypt it. We would typically use 2,048 bits are more, but, in this example, we will use 1,024 bit keys:

package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"fmt"
"flag"
"crypto/x509"
"encoding/pem"
)
func ExportPublicKeyAsPemStr(pubkey *rsa.PublicKey) string {
pubkey_pem := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY",Bytes: x509.MarshalPKCS1PublicKey(pubkey)}))
return pubkey_pem
}
func ExportPrivateKeyAsPemStr(privatekey *rsa.PrivateKey) string {
privatekey_pem := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY",Bytes: x509.MarshalPKCS1PrivateKey(privatekey)}))
return privatekey_pem
}
func ExportMsgAsPemStr(msg []byte) string {
msg_pem := string(pem.EncodeToMemory(&pem.Block{Type: "MESSAGE",Bytes: msg}))
return msg_pem
}

func main() {
 bits := 1024
flag.Parse()
args := flag.Args()
 m:=args[0]

 bobPrivateKey, _ := rsa.GenerateKey(rand.Reader,bits)

bobPublicKey := &bobPrivateKey.PublicKey
 fmt.Printf("%s\n",  ExportPrivateKeyAsPemStr(bobPrivateKey))
 fmt.Printf("%s\n", ExportPublicKeyAsPemStr(bobPublicKey))
 message := []byte(m)
label := []byte("")
hash := sha256.New()

 ciphertext, _ := rsa.EncryptOAEP(hash, rand.Reader, bobPublicKey, message,label)

 fmt.Printf("%s\n",ExportMsgAsPemStr(ciphertext))

 plainText, _:= rsa.DecryptOAEP(hash, rand.Reader, bobPrivateKey, ciphertext, label)
 fmt.Printf("RSA decrypted to [%s]", plainText)
}

The great advantage with Go is that it can be installed in most operating systems, and then can be compiled into an executable version. We first create this code as file called “rsa.go” and then compile with:

go build rsa.go

In Microsoft Windows, this then creates an executable file named “rsa.exe”, and which can be run as a stand-alone program, and where we pass the message as argument. A sample run is:

Private Key:
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDtRdbSFXRTmoXGqdZUyHyfTSscZmIxQKojNrMZ0TizK3kwYEHz
ucsJsXy2vSIntO+oX/kX3KdisiOR+p5RnLFunPsdqFIh15O5ulQY4478ZCgBl25f
dHD3aaAkVgCSDKt9k48fNJ1fCPq7mumk5rBJhkVjjMZj14KCRAZb5SwIEwIDAQAB
AoGBAOOOOFFxXAgWSThXiAP153dMJg1tr7x2vPVar3gSLOPAzNB1cKsTw8L/IpGL
YGdeYv5DVPzqlOnV2MFW72Fr+sk3KzOxFhCCvZNkxfub2z2Rnf8e+yYx2KjOprtA
irRjbDfqHie78C1Z7OnibqCtAGMFGWI4SgoJCYZheXc8hz/RAkEA9NPlrSVyh0Ev
7oTShBl1d6rAaJfEDjbG1ZisWmETru3NuHRYG5guVQlTCJsN1z9apLdCuG1IpTSo
1cg0O9YGmwJBAPgZr0csbxZlWt6mWhlb//YqFtUA0qpzWPb9EhqcTPjxrnH7/6rN
Iea2OXx8YeBsFxqf1hl4Rop/m4AwZLlN3+kCQFM8S0Sfi51ySyJzY8LniOlDUyD8
H/qZIuZxfn9Hq9J4JM3GOEJBbdcZUXKGjKEWd/GyIGvlM6J/EbuE0kVZkWsCQCit
RWCc92WrnndsvM71l4TLp8yqgt+xY7+zBFnakIAsV9aWY3ekhE9oRwqS9hUug6c4
14h7gM1KWLtus8Tx8KkCQQDPYf4eJp/Rv3eqNWdFZir8WmaE7phIoQ3NpmjiG0i2
DGIv4ypxeW2t0PxqOakI7my66BCkOoHssI/o18prRAOD
-----END RSA PRIVATE KEY-----
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAO1F1tIVdFOahcap1lTIfJ9NKxxmYjFAqiM2sxnROLMreTBgQfO5ywmx
fLa9Iie076hf+Rfcp2KyI5H6nlGcsW6c+x2oUiHXk7m6VBjjjvxkKAGXbl90cPdp
oCRWAJIMq32Tjx80nV8I+rua6aTmsEmGRWOMxmPXgoJEBlvlLAgTAgMBAAE=
-----END RSA PUBLIC KEY-----
OAEP encrypted message
-----BEGIN MESSAGE-----
SfWJdEcpfJmV7Am0zHLl5PyJTxb0yJV0CR/XLL1dxuvKkUZoUrs7C7DJJXZdklRv
95dj1xPajghOzd2DruFEy30OV6MevBQGHiigBvtX2KvnpDW4ROGZ+lo8HDeH/MGg
52f6s5KUkGUzucd0ZAX5myIkOJ5XfF+Xc6Uou3ZB1Eg=
-----END MESSAGE-----

OAEP decrypted to [abc]

In this case we convert the public key, the private key and the message into a PEM format, as this is easy to distribute. The OAEP (Optimal Asymmetric Encryption Padding) format is used to pad the message and is defined in the PKCS#1 v2 standard.

If we want to run without compiling, we can run:

go run rsa.go

Conclusions

While RSA has become rather slow for modern day key sizes, and it is being replaced by ECC (Elliptic Curve Cryptography) in many applications, it is still around, and useful in creating applications that require a simple encryption/decryption process. A common application is to protect a symmetric key.

So while Python and Node.js are great as scripting languages, some times we need the speed of a compiled language, and Go gives us the power of C++ but in a form that can be easily setup, without the complexity of the compilation and linking process that C++ brings.