I'm working with Golang's RSA encryption library. The following is the function to encrypt a message:
func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error)
The random parameter is used as a source of entropy to ensure that encrypting the same message twice doesn't result in the same ciphertext. This parameter allow to use linux functions like getrandom(2) if available or /dev/urandom otherwise that serves as a random number generator by accessing environmental noise collected from devices and other sources. I don't want the EncryptOAEP function to use the functions of the operating system (getrandom(2) or /dev/urandom) to generate the random number. I need to generate a random number by myself (that is, outside the EncryptOAEP function) and then insert it into it. Is that possible with this library? In case it is not, what Golang's library could I use to achieve this behavior? I hope I was clear enough, any help will be appreciated, thanks!
By design, it is possible and it is easy to do. Provide any io.Reader
as the random
argument.
Here's an example from the Go crypto/rsa
package. I replaced the crypto/rand
io.Reader
with a math/rand
io.Reader
.
package main
import (
"crypto/rsa"
"crypto/sha256"
"fmt"
"math/big"
"math/rand"
"os"
"time"
)
func main() {
secretMessage := []byte("send reinforcements, we're going to advance")
label := []byte("orders")
// crypto/rand.Reader is a good source of entropy for randomizing the
// encryption function.
// rng := rand.Reader
// However, you can use any io.Reader.
// For example, math/rand.Reader
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
ciphertext, err := rsa.EncryptOAEP(sha256.New(), rng, &test2048Key.PublicKey, secretMessage, label)
if err != nil {
fmt.Fprintf(os.Stderr, "Error from encryption: %s
", err)
return
}
// Since encryption is a randomized function, ciphertext will be
// different each time.
fmt.Printf("Ciphertext: %x
", ciphertext)
}
func fromBase10(base10 string) *big.Int {
i, ok := new(big.Int).SetString(base10, 10)
if !ok {
panic("bad number: " + base10)
}
return i
}
var test2048Key *rsa.PrivateKey
func init() {
test2048Key = &rsa.PrivateKey{
PublicKey: rsa.PublicKey{
N: fromBase10("14314132931241006650998084889274020608918049032671858325988396851334124245188214251956198731333464217832226406088020736932173064754214329009979944037640912127943488972644697423190955557435910767690712778463524983667852819010259499695177313115447116110358524558307947613422897787329221478860907963827160223559690523660574329011927531289655711860504630573766609239332569210831325633840174683944553667352219670930408593321661375473885147973879086994006440025257225431977751512374815915392249179976902953721486040787792801849818254465486633791826766873076617116727073077821584676715609985777563958286637185868165868520557"),
E: 3,
},
D: fromBase10("9542755287494004433998723259516013739278699355114572217325597900889416163458809501304132487555642811888150937392013824621448709836142886006653296025093941418628992648429798282127303704957273845127141852309016655778568546006839666463451542076964744073572349705538631742281931858219480985907271975884773482372966847639853897890615456605598071088189838676728836833012254065983259638538107719766738032720239892094196108713378822882383694456030043492571063441943847195939549773271694647657549658603365629458610273821292232646334717612674519997533901052790334279661754176490593041941863932308687197618671528035670452762731"),
Primes: []*big.Int{
fromBase10("130903255182996722426771613606077755295583329135067340152947172868415809027537376306193179624298874215608270802054347609836776473930072411958753044562214537013874103802006369634761074377213995983876788718033850153719421695468704276694983032644416930879093914927146648402139231293035971427838068945045019075433"),
fromBase10("109348945610485453577574767652527472924289229538286649661240938988020367005475727988253438647560958573506159449538793540472829815903949343191091817779240101054552748665267574271163617694640513549693841337820602726596756351006149518830932261246698766355347898158548465400674856021497190430791824869615170301029"),
},
}
test2048Key.Precompute()
}
Playground: https://play.golang.org/p/KtqUuDC2Tai
Output:
Ciphertext: 47516ff9863897f8f5344d07bca363515856ace56fed5451ede414eb6771eff357f09ca67f07d0d918b6e7107975f83afc4eebc932a7d9ba3f48c3f70399af88917c852e46a3d43eaa9bc563c7780bf7cf090c0b5e1690ac77af9e7c8cc6ec0d2fb729eed3fb45c824754bfd898e02eee8dae88b4fb3277f6970dbb0b929da7c14d245e51ed3a3e63127efc3e4c438adcfce78bbc1117a134f5a9dd62f9ebc14f125561c959ce6963a2b8605687ab568ec570295bb8f25477c7bbcb7303d96e888a0150e23ea0dd4880fefe40d86567518784d7f54c594f2c0e576a14c210201bf9d75fbd96b70fdd793c28ffecaa5c036b2949dba6e66004ec2f0e676095f1c