且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用初始密钥生成公钥/私钥对

更新时间:2023-01-18 10:16:17

实际上很容易。

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

The algorithm for generating an RSA key pair boils down to finding a set of big, prime numbers, that fulfil some algebraical properties and that are of appropriate size. If you need a 2048 bit RSA key, you will typically look for 2 prime number, each having a a rough length of 1024 bits.

查找过程质数是反复试验的:您随机选择一个适当大小的整数,然后测试它是否为质数。如果不是,则重试。

The process of finding a prime number is trial-and-error: you randomly pick an integer of appropriate size, and test if it is prime. If it is not, you retry.

在现实世界中,驱动算法的随机生成器是确定性PRNG,其中植入了适当熵的秘密(例如, 128位真正的随机性。)

In the real world, the random generator that drives the algorithm is a deterministic PRNG which is seeded with a secret of appropriate entropy (e.g. 128 bits of true randomness).

在您的情况下,PRNG种子可以从用户机密甚至从另一个密钥派生(当然,这是秘密的)。推导应使用诸如 HKDF PBKDF2 等。

In your case, the PRNG seed can be derived from a user secret or even from another key (provided it is secret of course). Derivation should be performed with a salted KDF like HKDF, PBKDF2, etc.

您未指定要使用的密码库:无论是什么,您都必须清楚它是如何吸引随机性以及如何定义PRNG的种子的。

You don't specify which crypto library you use: whatever it is, you must be clear on how it draw randomness and how to define the seed of the PRNG.

示例(在Python 2.x中):

Example (in 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. 派生密钥不能比第一个密钥更强(例如,该算法不会神奇地产生熵。如果密钥或密码短语较短,则最终会得到一个弱的派生密钥。