当前位置: 首页 > 知识库问答 >
问题:

Go中加密/解密的源文本、密钥大小关系

轩辕嘉平
2023-03-14

在下面的代码中(也在http://play.golang.org/p/77fRvrDa4A但是在浏览器中需要“太长的时间来处理”)124字节版本的sourceText不会加密,因为1024的“消息对于RSA公钥大小来说太长”。它和更长的124字节sourceText版本可使用2048位密钥大小。

我的问题是如何准确计算rsa中的密钥大小。GenerateKey给定源文本的字节长度?(一个小段落大小的文本在4096键大小下需要将近10秒,直到运行时我才知道源文本的长度。)

这里有一个非常简短的讨论https://stackoverflow.com/a/11750658/3691075,但我不清楚,因为我不是加密人。

我的目标是加密、存储在数据库中并解密大约300字节长的JSON字符串。我控制发送端和接收端。文本加密一次,解密多次。任何战略提示都将不胜感激。

package main

import (
    "crypto/md5"
    "crypto/rand"
    "crypto/rsa"
    "fmt"
    "hash"
    "log"
    "time"
)

func main() {
     startingTime := time.Now()
     var err error
     var privateKey *rsa.PrivateKey
     var publicKey *rsa.PublicKey
     var sourceText, encryptedText, decryptedText, label []byte

    // SHORT TEXT 92 bytes
     sourceText = []byte(`{347,7,3,8,7,0,7,5,6,4,1,6,5,6,7,3,7,7,7,6,5,3,5,3,3,5,4,3,2,10,3,7,5,6,65,350914,760415,33}`)
     fmt.Printf("\nsourceText byte length:\n%d\n", len(sourceText))

    // LONGER TEXT 124 bytes
    // sourceText = []byte(`{347,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,65,350914,760415,33}`)
    // fmt.Printf("\nsourceText byte length:\n%d\n", len(sourceText))

    if privateKey, err = rsa.GenerateKey(rand.Reader, 1024); err != nil {
         log.Fatal(err)
    }

    // fmt.Printf("\nprivateKey:\n%s\n", privateKey)

    privateKey.Precompute()

    if err = privateKey.Validate(); err != nil {
         log.Fatal(err)
    }

     publicKey = &privateKey.PublicKey

     encryptedText = encrypt(publicKey, sourceText, label)
     decryptedText = decrypt(privateKey, encryptedText, label)

     fmt.Printf("\nsourceText: \n%s\n", string(sourceText))
     fmt.Printf("\nencryptedText: \n%x\n", encryptedText)
     fmt.Printf("\ndecryptedText: \n%s\n", decryptedText)

     fmt.Printf("\nDone in %v.\n\n", time.Now().Sub(startingTime))
}

func encrypt(publicKey *rsa.PublicKey, sourceText, label []byte) (encryptedText []byte) {
     var err error
     var md5_hash hash.Hash
     md5_hash = md5.New()
     if encryptedText, err = rsa.EncryptOAEP(md5_hash, rand.Reader,           publicKey, sourceText, label); err != nil {
         log.Fatal(err)
     }
     return
}

func decrypt(privateKey *rsa.PrivateKey, encryptedText, label []byte) (decryptedText []byte) {
     var err error
     var md5_hash hash.Hash
     md5_hash = md5.New()
     if decryptedText, err = rsa.DecryptOAEP(md5_hash, rand.Reader, privateKey, encryptedText, label); err != nil {
         log.Fatal(err)
     }
     return
}

共有1个答案

储臻
2023-03-14

通常不会根据有效负载计算RSA密钥大小。您只需根据安全性(越大越好)和性能(越小越好)之间的折衷选择一个RSA密钥大小。如果这样做了,使用混合加密结合AES或其他对称密码来实际加密数据。

如果有效负载不超过300字节,并且您使用的是OAEP(至少42字节的填充),那么您可以轻松计算最小密钥大小:

(300 + 42) * 8 = 2736 bit

这已经是一个合理大小的关键。根据今天的规范,它提供了良好的安全性,而且速度相当快。没有必要为此应用混合加密方案。

现在,您可能注意到密钥大小不是2的幂。这不是问题。但是,您应该使用64位的倍数的密钥大小,因为处理器使用32位和64位原语来执行实际计算,因此您可以在不降低性能的情况下提高安全性。下一个这样的密钥大小是:

ceil((300 + 42) * 8 / 64.0) * 64 = 2752 bit

以下是一些实验结果,一些语言/框架接受(不是性能方面)作为关键大小:

  • Golang:1位和

在您决定使用某种特定的键大小之前,您应该检查所有框架都支持该大小。如你所见,结果千差万别。

我试着写了一些不同密钥大小的密钥生成、加密和解密的性能测试:512, 513, 514, 516, 520, 528, 544, 576。因为我不知道怎么走,所以很难把握好时机。所以我选择了Java和密码。加密代码可能非常错误,因为520位和528位密钥的密钥生成速度比其他密钥大小快7个数量级,其他密钥大小对于小密钥大小窗口或多或少是恒定的。

Java密钥生成非常清楚,513位密钥的生成比512位密钥的生成慢2-3倍。除此之外,结果几乎是线性的。该图是标准化的,迭代次数为1000,整个keygen-enc-dec周期。

解密在544位略微下降,这是32位的倍数。由于它是在32位debian上执行的,这可能意味着确实有一些性能改进,但另一方面,对于该密钥大小,加密速度较慢。

因为这个基准测试没有在Go中完成,所以我不会给出任何关于开销有多小的建议。

 类似资料:
  • 问题内容: 我正在尝试编写一个使用RSA密钥对加密和解密纯文本文件的实用程序。RSA密钥是使用ssh-keygen生成的,并照常存储在.ssh中。 我在理解如何使用Go语言crypto和crypto / rsa软件包时遇到问题吗?有关这些文档的文档很少(甚至更多,因为我对加密还不熟悉),并且示例很少。我检查了rsa_test.go文件是否有任何线索,但这只会使我更加困惑。 简而言之,我试图从.ss

  • 任务:凯撒算法(密码(c))通过按密钥(k)位置“旋转”每个字母来加密消息。 实现:ci=(pi k)mod26,其中ci是密码,pi是明文,k是密钥。 我的伪代码: 从命令行参数获取密钥 将键(k)转换为整数 提示用户输入纯文本(pi) 对于每个纯文本字符,保留大小写(使用C中的isalpha、isupper和islower函数)。 最后,按键移动明文字符,例如“回家!”——“Hp Ipnf!”

  • 也许你能帮我。非常感谢!

  • 问题内容: 我有以下Go代码 输出是 使用以下CryptoJS加密 并且可以用解密 输出是-这是正确的输出 为什么Go会有不同的输出? 问题答案: 请检查您的错误。总是 https://play.golang.org/p/dRLIT51u4I 更具体地说,字节75处的值为,超出了base64可用字符的范围。在ascii中,它是ENQ(查询)字符。至于为什么它最终出现在您的最终base64字符串中,

  • 这是我的密码 抱歉,如果我的代码一团糟。