首页 > 解决方案 > 我是否应该验证 RSA 包生成的用户密钥对是唯一的(其他用户没有相同的密钥对)?

问题描述

我最近使用数字签名,想弄清楚如何让每个注册的用户都有自己的密钥对用于编码和解码过程。我使用 Go 构建这种系统,并使用Go中的crypto/rsa 包。我已经阅读了一些关于如何制作安全数字签名并找到很多东西的文章。然后,我尝试构建用于保护非对称加密过程的第一件事。

然后,我面临的第一个问题是我问自己一个问题“我应该创建一个验证,以确保没有其他用户拥有 RSA 包生成的密钥对吗?” 这样可以确保每个用户都不会因为他们拥有相同的密钥对而意外或故意假装为其他用户(即使机会非常小)。

请给我一些关于这种情况的见解。如果我的问题不够清楚,请随时提出或投诉,我真的很难为我的用户和系统考虑任何安全方面。

import (
    "crypto/rand"
    "crypto/rsa"
    "encoding/pem"
    ...
)
...
func createKeyPairs(userRegistered *User) (err error) {
    keyPairs, err := rsa.GenerateKey(rand.Reader, 4096)
    if err != nil {
        return err
    }

    // SHOULD I ADD SOME VALIDATION FOR THE KEYPAIRS GENERATED BY CRYPTO RSA AND RAND PACKAGE HERE

    caPrivateKeyPEMFile, err := os.Create(userRequestingCA.ID + "PrivateKey.pem")
    pem.Encode(caPrivateKeyPEMFile, &pem.Block{
        Type:  "RSA PRIVATE KEY",
        Bytes: x509.MarshalPKCS1PrivateKey(keyPairs),
    })

    caPublicKeyPEMFile, err := os.Create(userRequestingCA.ID + "PublicKey.pem")
    pem.Encode(caPublicKeyPEMFile, &pem.Block{
        Type:  "RSA PUBLIC KEY",
        Bytes: x509.MarshalPKCS1PublicKey(&keyPairs.PublicKey),
    })
}

标签: validationsecuritygocryptographyrsa

解决方案


不,你不应该。

主要是因为严格的私钥比较是不够的,你需要确保模数中的两个素数不同。

第二个原因是它几乎毫无意义:选择相同素数的可能性非常低,你只是在浪费时间。

给定一个 4096 位 RSA 密钥,您正在寻找两个 2048 位素数。这些碰撞的可能性很小。

它可能有用的一种情况是,如果你的机器上有可怕的熵。但是你可能还有其他问题,这可能是一个单独的问题。

有关模素数为何重要(与原始密钥内容相反)的更多详细信息,以及计算素数冲突可能性的详细信息,请参阅此 security.se 问题

第三个原因是它需要您保留所有用户私钥的参数。您绝对不应该,而且您可能一开始就不应该代表他们生成密钥对。


推荐阅读