3

我正在寻找一种方法,使用户能够使用提供给他/她的初始密钥生成一对公钥/私钥。我不知道这是否称为分层密钥生成或多级密钥生成或其他。较高级别的密钥能够解密较低级别的数据并不重要,我只需要使用另一个密钥生成对。

我看过一些文章,但它们都只是理论上的。有没有办法为 RSA 实现这一目标?

4

1 回答 1

6

实际上这很容易。

生成 RSA 密钥对的算法归结为找到一组满足某些代数性质且大小合适的大素数。如果您需要 2048 位 RSA 密钥,您通常会寻找 2 个素数,每个素数的粗略长度为 1024 位。

寻找素数的过程是反复试验:你随机选择一个适当大小的整数,并测试它是否为素数。如果不是,请重试。

在现实世界中,驱动算法的随机生成器是一个确定性的 PRNG,它以适当熵的秘密(例如 128 位的真正随机性)作为种子。

在您的情况下,PRNG 种子可以从用户机密甚至从另一个密钥(当然,前提是它是机密的)派生。应使用盐渍 KDF(如HKDFPBKDF2等)进行推导。

您无需指定使用哪个加密库:无论它是什么,您都必须清楚它如何绘制随机性以及如何定义 PRNG 的种子。

示例(在 Python 2.x 中):

from Crypto.PublicKey import RSA
from Crypto.Hash import HMAC
from struct import pack

# The first key could also be read from a file
first_key = RSA.generate(2048)

# Here we encode the first key into bytes and in a platform-independent format.
# The actual format is not important (PKCS#1 in this case), but it must
# include the private key.
encoded_first_key = first_key.exportKey('DER')

seed_128 = HMAC.new(encoded_first_key + b"Application: 2nd key derivation").digest()

class PRNG(object):

  def __init__(self, seed):
    self.index = 0
    self.seed = seed
    self.buffer = b""

  def __call__(self, n):
    while len(self.buffer) < n:
        self.buffer += HMAC.new(self.seed +
                                pack("<I", self.index)).digest()
        self.index += 1
    result, self.buffer = self.buffer[:n], self.buffer[n:]
    return result

second_key = RSA.generate(2048, randfunc=PRNG(seed_128))

要记住的缺点是:

  1. 一旦第一个密钥被泄露,派生密钥就会被泄露。
  2. 派生密钥不能比第一个密钥强(例如,该算法不会神奇地产生熵。如果密钥或密码很短,那么您最终会得到一个弱派生密钥。
于 2013-08-16T06:17:52.273 回答