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。不要那样做。
以下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。不要那样做。