首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Go中用于加密/解密的源文本、密钥大小关系

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

Stack Overflow用户
提问于 2015-06-01 15:39:46
回答 1查看 1.9K关注 0票数 0

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

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

https://stackoverflow.com/a/11750658/3691075对此进行了非常简短的讨论,但我不太清楚,因为我不是一个神秘的家伙。

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

代码语言:javascript
复制
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
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-01 16:33:46

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

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

代码语言:javascript
复制
(300 + 42) * 8 = 2736 bit

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

现在,您可能会注意到键大小不是2. 这不是问题的幂。但是,您应该使用64位倍数的键大小,因为处理器使用32位和64位原语来进行实际计算,因此可以在不影响性能的情况下增加安全性。下一个关键尺寸是:

代码语言:javascript
复制
ceil((300 + 42) * 8 / 64.0) * 64 = 2752 bit

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

  • 戈朗:1位的倍数和>= 1001 (sic!)旧ideone.com
  • PyCrypto: 256位的倍数和>= 1024的本地安装
  • C#:16位的倍数和>= 512使用的ideone.com
  • Groovy: 1位的倍数和>= 512本地安装
  • Java: 1位的倍数和>= 512使用ideone.com: Java & Java7
  • PHP/OpenSSL : 128位的倍数和>= 640使用的ideone.com
  • Crypto++:1位的倍数和>= 16的本地安装,3的最大验证韧性

在决定使用某种特定的键大小之前,应该检查所有框架是否支持该大小。正如你所看到的,结果大相径庭。

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

在Java中,密钥生成非常清楚,因为513位键的生成速度是512位键的2-3倍。除此之外,结果几乎是线性的。对于整个keygen-enc-dec循环,图被规范化,迭代次数为1000。

解密使在544位,这是一个32位的倍数稍微倾斜.因为它是在32位debian上执行的,这可能意味着确实有一些性能改进,但是另一方面,对于这个密钥大小,加密要慢一些。

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30577630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档