在Golang中进行确定性RSA加密 – 如何在多次加密中获得相同的给定消息结果

huangapple go评论68阅读模式
英文:

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

问题

对于下面的RSA加密代码,每次加密相同的消息时,结果都会不同。我发现这是由于rsa.EncryptOAEP函数中的rand.Reader导致的,根据文档,这样做可以增加安全性。但是我希望每次进行RSA加密时,相同的消息都能得到相同的结果。在Golang中如何实现这样的要求?有一个类似的问题,但似乎答案并不是关于如何实现这个要求的。谢谢!

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链码(区块链智能合约)时需要确定性的加密结果。谢谢大家的警告。那么我想我应该关注如何在链码中启用这些加密算法。如果有帮助的话,这是一个相关问题供后来者参考。

英文:

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

Update: I want to do deterministic RSA because I want deterministic encryption results when using Hyperledger Fabric chaincode (blockchain smart contract) which requires deterministic outputs. Thank you all for the warnings. Then I guess I should focus on how to enable these encryption algorithms in chaincode. Relevant question for later comers' information if it helps 在Golang中进行确定性RSA加密 – 如何在多次加密中获得相同的给定消息结果

答案1

得分: 3

这种方法,正如你所读到的,会破坏算法的非常重要的安全特性,绝不能用于保护任何类型的实时系统。然而,对于某些测试和开发目的,它可能是有用的。我会假设这就是你的意图。

关键在于 rsa.EncryptOAEP 接受一个任意的 io.Reader 作为熵源。它并不要求这个熵源是一个 rand.Reader。如果你不关心系统的安全性,它可以是任何你喜欢的东西。例如,你可以构建一个“零读取器”,它只会永远返回零:

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{} 作为你的熵源传递进去:

// !!! 这个调用的安全性完全被破坏了 !!!
// !!! 绝不能在实时数据上使用它         !!!
encryptedBytes, err := rsa.EncryptOAEP(
    sha256.New(),
    zeroReader{}, // !!! 我故意在这里破坏了安全性 !!!
    &publicKey,
    []byte(message),
    nil)

如果你确实打算在任何实时数据上使用它,那么你必须重新设计你的系统,不再需要这个。就像你链接的问题一样,通常人们试图这样做是因为他们误解了 RSA。不要这样做。

英文:

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

huangapple
  • 本文由 发表于 2022年4月26日 23:50:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/72016916.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定