用大型公共指数生成RSA密钥
步骤1。我分别为爱丽丝和鲍勃生成了RSA键对,并使用爱丽丝的公共密钥对爱丽丝的消息进行了加密。
第2步。我将鲍勃公共密钥的公共指数乘以爱丽丝私钥的私人指数,以拥有一个新数字。
步骤3。我生成了一个新的RSA公共密钥,keyregen:= rsa.publickey {n:keypubalicen,e:enew}
> 1。
步骤4。现在,鲍勃可以收到原始消息,这是预期的输出。
代码:
package main
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"fmt"
"math/big"
)
func main() {
keyPriAlice, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
panic(err)
}
keyPubAlice := keyPriAlice.PublicKey
keyPriAliceD := keyPriAlice.D
keyPubAliceN := keyPubAlice.N
keyPriBob, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
panic(err)
}
keyPubBob := keyPriBob.PublicKey
keyPubBobE := big.NewInt(int64(keyPubBob.E))
message := "secret"
encryptedBytes, err := rsa.EncryptOAEP(
sha256.New(),
rand.Reader,
&keyPubAlice,
[]byte(message),
nil)
if err != nil {
panic(err)
}
z := new(big.Int)
y := z.Mul(keyPriAliceD, keyPubBobE)
ENew := int(y.Int64())
keyRegen := rsa.PublicKey{N: keyPubAliceN, E: ENew}
reEncryptedBytes, err := rsa.EncryptOAEP(
sha256.New(),
rand.Reader,
&keyRegen,
[]byte(encryptedBytes),
nil)
if err != nil {
panic(err)
}
// decrypt the re-encrypted plaintext using Bob's private key
decryptedBytes, err := keyPriBob.Decrypt(nil, reEncryptedBytes, &rsa.OAEPOptions{Hash: crypto.SHA256})
fmt.Println("decryptedBytes:", decryptedBytes)
}
Step 1. I generated RSA key pairs for Alice and Bob, respectively, and encrypted a message for Alice using Alice's public key.
Step 2. I multiplied the public exponent of Bob's public key with the private exponent of Alice's private key to have a new number.
Step 3. I generated a new RSA public key by keyRegen := rsa.PublicKey{N: keyPubAliceN, E: ENew}
and used it to encrypt the message encrypted in step 1.
Step 4. I decrypted the re-encrypted message from step 3 using Bob's private key. Theoretical now Bob can get the original message, which is the expected output.
Problem: However, I found that the public exponent in rsa.PublicKey should be an int
, while my new public exponent generated in step 2 is a big.Int
. I converted it into int
and used the newly generated public key to do the encryption but error panic: crypto/rsa: public exponent too small
happened. Also I guess I should not do such a conversion because the new number is probably larger than int
range. Then are there any ways to generate a new RSA key with the large public exponent? Thank you!
Codes:
package main
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"fmt"
"math/big"
)
func main() {
keyPriAlice, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
panic(err)
}
keyPubAlice := keyPriAlice.PublicKey
keyPriAliceD := keyPriAlice.D
keyPubAliceN := keyPubAlice.N
keyPriBob, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
panic(err)
}
keyPubBob := keyPriBob.PublicKey
keyPubBobE := big.NewInt(int64(keyPubBob.E))
message := "secret"
encryptedBytes, err := rsa.EncryptOAEP(
sha256.New(),
rand.Reader,
&keyPubAlice,
[]byte(message),
nil)
if err != nil {
panic(err)
}
z := new(big.Int)
y := z.Mul(keyPriAliceD, keyPubBobE)
ENew := int(y.Int64())
keyRegen := rsa.PublicKey{N: keyPubAliceN, E: ENew}
reEncryptedBytes, err := rsa.EncryptOAEP(
sha256.New(),
rand.Reader,
&keyRegen,
[]byte(encryptedBytes),
nil)
if err != nil {
panic(err)
}
// decrypt the re-encrypted plaintext using Bob's private key
decryptedBytes, err := keyPriBob.Decrypt(nil, reEncryptedBytes, &rsa.OAEPOptions{Hash: crypto.SHA256})
fmt.Println("decryptedBytes:", decryptedBytes)
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为此,您可能需要使用其他库。在大多数现代的RSA环境中,我们希望D,私人指数,出于安全原因,但出于绩效原因,我们希望E很小。实际上,我所看到的绝大多数安全实现选择了65537,它是安全且快速的(由于恰好包含两个)。
GO库是基于以下事实做出的假设:实际上,每个不是漏洞利用的现实场景都需要一个小的E,E将适合INT,这可能是富有的,但最终是合理的。您可能会发现OPENSL更适合此目的,因为它往往对传递给它的数据做出更少的假设。
You'll probably need to use a different library for this. In most modern RSA contexts, we want d, the private exponent, to be large for security reasons, but we want e to be small for performance reasons. As a practical matter, the vast majority of secure implementations I've seen choose 65537 for e, which is secure and fast (due to containing exactly two ones).
The Go library has made the assumption, based on the fact that practically every real-world scenario that isn't an exploit wants a small e, that e will fit into an int, which may have been improvident, but is ultimately reasonable. You may find that OpenSSL is more suitable for this purpose, since it tends to make fewer assumptions about the data passed to it.