Golang 中的确定性 RSA 加密 - 如何在多次加密下为给定消息获得相同的结果

Deterministic RSA encryption in Golang - how to get same result for a given message under mutiple times of encryption

以下RSA加密的代码,我每次对同一条消息加密,结果都不一样。我发现这是由于 rsa.EncryptOAEP 函数中的 rand.Reader 根据 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 使其更安全,但似乎答案不是关于如何实现这一点。谢谢!

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)   
}

更新: 我想做确定性 RSA,因为在使用需要确定性输出的 Hyperledger Fabric 链码(区块链智能合约)时我想要确定性加密结果。谢谢大家的警告。那么我想我应该关注如何在链代码中启用这些加密算法。 Relevant question 如有帮助,欢迎后来者指教:)

如您所见,这种方法破坏了算法的非常重要的安全功能,绝不能用于保护任何类型的实时系统。但是,对于某些类型的测试和开发的目的,它可能是有用的。我会假设这就是你想要用它做的。

关键是 rsa.EncryptOAEP 接受任意 io.Reader 的熵。 不需要这是一个rand.Reader。如果您不关心系统的安全性,可以随心所欲。例如,您可以构建一个“零 reader”,它只是 returns 永远归零:

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

这样,您可以将 zeroReader{} 作为您的熵传递:

// !!! 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)

如果您确实打算将它用于任何类型的实时数据,那么您必须重新设计您的系统以不需要它。就您 link 的问题而言,人们经常尝试这样做是因为他们误解了 RSA。不要那样做。

Playground