Home > other >  Deterministic RSA encryption in Golang - how to get same result for a given message under mutiple ti
Deterministic RSA encryption in Golang - how to get same result for a given message under mutiple ti

Time:04-27

For the codes below of RSA encryption, every time when I do the encryption for the same message, the result would be different. I found that this is due to the rand.Reader in the rsa.EncryptOAEP function to make it more secure according to the doc. But I want the same result for the same message every time when I do the RSA encryption. How to do so using Golang? There is a similar question but it seems that answers are not about how to achieve this. Thank you!

package main

import (
    "crypto"
    "crypto/rand"
    "crypto/rsa"
    "crypto/sha256"
    "fmt"
)

func main() {
    privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
    if err != nil {
        panic(err)
    }
    publicKey := privateKey.PublicKey  
    message := "super secret message"
    encryptedBytes, err := rsa.EncryptOAEP(
        sha256.New(),
        rand.Reader,
        &publicKey,
        []byte(message),
        nil)
    if err != nil {
        panic(err)
    }
    fmt.Println("encrypted bytes: ", encryptedBytes)   
}

CodePudding user response:

This approach, as you've read, breaks very important security features of the algorithm, and must never be used to secure live systems of any kind. However, for the purposes of certain kinds of testing and development, it can be useful. I will assume that this is what you mean to do with it.

The key is that rsa.EncryptOAEP accepts an arbitrary io.Reader for its entropy. It does not require this to be a rand.Reader. If you do not care about the security of the system, it can be whatever you like. For example, you could build a "zero reader" that just returns zeros forever:

type zeroReader struct{}
func (z zeroReader) Read(p []byte) (n int, err error) {
    for i, _ := range p {
        p[i] = 0
    }
    n = len(p)
    return
}

With that, you can pass zeroReader{} as your entropy:

// !!! The security of this call is completely broken !!!
// !!! It must never be used on live data             !!!
encryptedBytes, err := rsa.EncryptOAEP(
    sha256.New(),
    zeroReader{}, // !!! I am intentionally breaking the security here !!!
    &publicKey,
    []byte(message),
    nil)

If you do mean to use this for any kind of live data, then you must redesign your system to not require this. As in the case of the question you link, often people try to do this because they misunderstand RSA. Don't do that.

Playground

  • Related