-
-
Save fuadarradhi/cde6e187761b846e7416554205727d3c to your computer and use it in GitHub Desktop.
RSA OAEP SHA256 encryption in Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"crypto/rand" | |
"crypto/rsa" | |
"crypto/sha256" | |
"crypto/x509" | |
"encoding/base64" | |
"encoding/pem" | |
// I deliberately don't use fmt package in this file | |
// so that error messages can be directed to Stderr | |
// and can be managed with shell scripts. | |
// Previous versions did use fmt. | |
"os" | |
) | |
var ( | |
hash = sha256.New() | |
salt = rand.Reader | |
msg = "This is a secret message" | |
rsaPubKey *string | |
rsaPriKey *string | |
) | |
func main() { | |
// Example of a command using environment variables: | |
// $ RSA_PUB_KEY=$(< path/to/pub_key_file) RSA_PRIV_KEY=$(< path/to/priv_key_file) go run rsa.go | |
envPubKey := os.Getenv("RSA_PUB_KEY") | |
envPriKey := os.Getenv("RSA_PRIV_KEY") | |
if len(envPriKey) > 0 && len(envPubKey) > 0 { | |
rsaPubKey = &envPubKey | |
rsaPriKey = &envPriKey | |
} else { | |
// If key pair not given in the environment variables, use default pair. | |
// Default key pair is declared at the end of this file. | |
rsaPubKey = &defaultPubkey | |
rsaPriKey = &defaultPriKey | |
os.Stdout.Write([]byte("╭――――――――――――――――――――――――――――――――╮\n")) | |
os.Stdout.Write([]byte("│ Default key pair will be used. │\n")) | |
os.Stdout.Write([]byte("│ Provide enviroment variables │\n")) | |
os.Stdout.Write([]byte("│ RSA_PUB_KEY and RSA_PRIV_KEY │\n")) | |
os.Stdout.Write([]byte("│ to use your own key pair. │\n")) | |
os.Stdout.Write([]byte("╰――――――――――――――――――――――――――――――――╯\n")) | |
} | |
decrypt(encrypt(msg)) | |
} | |
func encrypt(plaintext string) string { | |
block, _ := pem.Decode([]byte(*rsaPubKey)) | |
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) | |
if err != nil { | |
os.Stderr.Write([]byte("Failed to parse public key\n")) | |
panic(err) | |
} | |
pub := pubInterface.(*rsa.PublicKey) | |
ciphertext, err := rsa.EncryptOAEP(hash, salt, pub, []byte(msg), nil) | |
if err != nil { | |
os.Stderr.Write([]byte("Failed to encrypt string\n")) | |
panic(err) | |
} | |
// Encode ciphertext in base64 for printing to screen. | |
encoded := base64.URLEncoding.EncodeToString(ciphertext) | |
os.Stdout.Write([]byte("Ciphertext:\n")) | |
os.Stdout.Write([]byte(encoded + "\n")) | |
return string(ciphertext) | |
} | |
func decrypt(ciphertext string) string { | |
block, _ := pem.Decode([]byte(*rsaPriKey)) | |
pri, err := x509.ParsePKCS1PrivateKey(block.Bytes) | |
if err != nil { | |
os.Stderr.Write([]byte("Failed to parse private key\n")) | |
panic(err) | |
} | |
plaintext, err := rsa.DecryptOAEP(hash, salt, pri, []byte(ciphertext), nil) | |
if err != nil { | |
os.Stderr.Write([]byte("Failed to decrypt string\n")) | |
panic(err) | |
} | |
os.Stdout.Write([]byte("Plaintext:\n")) | |
os.Stdout.Write(plaintext) | |
return string(plaintext) | |
} | |
var ( | |
defaultPubkey = ` | |
-----BEGIN PUBLIC KEY----- | |
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAscetx8F1Q7H67ZSgIcTw | |
zQfCf919iACii2o5sh+1l7N62nE9zBpSx3OEgNv64l8v4OchXMU8gKk28piExpdQ | |
kvzDW5VK7STmEuIZ7IqWKsZge1YmGDsyIFw74V9Uslhc05t7VKYhWWFPAKfouPPM | |
3ZKe5ZiALAjvLVIEUYYnQ452H2RJGuGYJeKvPiNtOwKSLA/ROwvE/1I+0S+gq1hd | |
+GbrYPJLfj77pkZJKnf/ye3rgbQglfBQzSHSDKuwC6xNZEWMR4DBzraE0MeKrNhN | |
4PFxKpkyVRPftrahbiTA6ohvoBsSyD+RdT1dRde4qbJGXuW6AQ2DQYNPWqTdVDNo | |
kwIDAQAB | |
-----END PUBLIC KEY----- | |
` | |
defaultPriKey = ` | |
-----BEGIN RSA PRIVATE KEY----- | |
MIIEpQIBAAKCAQEAscetx8F1Q7H67ZSgIcTwzQfCf919iACii2o5sh+1l7N62nE9 | |
zBpSx3OEgNv64l8v4OchXMU8gKk28piExpdQkvzDW5VK7STmEuIZ7IqWKsZge1Ym | |
GDsyIFw74V9Uslhc05t7VKYhWWFPAKfouPPM3ZKe5ZiALAjvLVIEUYYnQ452H2RJ | |
GuGYJeKvPiNtOwKSLA/ROwvE/1I+0S+gq1hd+GbrYPJLfj77pkZJKnf/ye3rgbQg | |
lfBQzSHSDKuwC6xNZEWMR4DBzraE0MeKrNhN4PFxKpkyVRPftrahbiTA6ohvoBsS | |
yD+RdT1dRde4qbJGXuW6AQ2DQYNPWqTdVDNokwIDAQABAoIBACnS6iVGdAn7AyeF | |
ga6wIF575twiBXhLffICiZRINXZ8+PgPEBTGVJcrrA6MshczgZYNiiHDHRq/tHea | |
PhJiYshRwrv3AWuM9LuYibTGXdGuXeBmQgwNURuf106MGObkNuJpf7hIZSwb4nQr | |
DGsGoDm4Vr15BR5W873bv7xWLUKNCpPwo65pGJHTCTjBm6AC0doQ/WbN+V9ly2B6 | |
uz2Afl9wrQlTZUUHLFuvO9IjukCCj0ZclPocsURA0j3TF47kXmZxhYT5wCerzZRO | |
tgfJXd0sGvoBZTS5OpEVG3ef/EFbyDLy76QwsItaphJlgCCyXwFOTDxDQQWd6uPA | |
3V9/lWECgYEA6p74OccfFythzHZN/SOk4bC5bUKWw6umE0h0t3lQN7bCtddDu2RH | |
xR4SFlIA8fL6Vp4BkseydRg3mMHz+UZ5E5EaRPWWQHU0Spn9qnrO0QTuWeQJlpN0 | |
6f0Am2pZeh6voRbbzAC3yKGI5frdDLtM2p2k/gbGlWTB5e0L2UGAUNkCgYEAwfrF | |
7UWIrCqx2abgsGNfHp4omwhfv8jpD4CGpXKGrHvnagGfLYABngbmIo0GLHyUR0Rm | |
wE2qfeDp+64vvNj+RV4lRME1PNFsWxaJ8eMUHr06lDO51Cy1lhTWymT4NXj+Esys | |
dFJvCElfwxbZjflyNf8hfkSa24Rfo6WoI9jV4UsCgYEA4HJZlrRVms2mjnmym/LI | |
Xhu5F7v3DJMdmh7bgVWtls7gsCKRqigBvKHKvc2PF+bQ86HOcYNWxkv3i8wnwJVZ | |
aI2MauHh7iHxd1ifYcKALVchSZ8sSP8hfmLJfOQdWwUWEO4UMLGTH3zgwNnfM7nO | |
iOj8mQMUYIB2OaYuipTt0ukCgYEAl4qRHAdJea81GCNtv38ybVoDwPIu00ZjBNBU | |
4GXzXkbCCCfSMhqhqNIc8fsYSqLcuDxwxWUnf4W5ZfyzoKYpJwogtXD3ZVb6fsLB | |
662KJ2WPoP4z+9Ud22zWTHHLEwM+AnPRemJ4CZJA9MkiFu88UYDKqrlv/XSRvugI | |
zlB07rcCgYEAueo9hE02p0iSqxXWru8zu7PxY8Gy2+tksMZb4PWB5C732BMr3ryP | |
lz5UUW+5iBe/z54HOdmBbVdd3G+fRlkCm9XUex0GlwaN3g45k8rcyJi/8iRexIpF | |
2c3olpk+wO+d7ciK+7Qc8uHYyZlnBxQu6FIRDTE/Y8QOkU97/BDSkYQ= | |
-----END RSA PRIVATE KEY----- | |
` | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment