ユーザーに提供された初期キーを使用して、ユーザーが公開/秘密キーのペアを生成できるようにする方法を探しています。これが階層的なキー生成またはマルチレベルのキー生成または他の何かと呼ばれるかどうかはわかりません。上位レベルのキーが下位レベルのデータを復号化できることは重要ではありません。別のキーを使用してペアを生成する必要があるだけです。
いくつかの記事を見てきましたが、それらはすべて理論上のものです。RSAでこれを達成する方法はありますか?
ユーザーに提供された初期キーを使用して、ユーザーが公開/秘密キーのペアを生成できるようにする方法を探しています。これが階層的なキー生成またはマルチレベルのキー生成または他の何かと呼ばれるかどうかはわかりません。上位レベルのキーが下位レベルのデータを復号化できることは重要ではありません。別のキーを使用してペアを生成する必要があるだけです。
いくつかの記事を見てきましたが、それらはすべて理論上のものです。RSAでこれを達成する方法はありますか?
実際にはかなり簡単です。
RSA 鍵ペアを生成するためのアルゴリズムは、いくつかの代数的特性を満たし、適切なサイズの大きな素数のセットを見つけることに要約されます。2048 ビットの RSA キーが必要な場合は、通常、それぞれがおよそ 1024 ビットの長さを持つ 2 つの素数を探します。
素数を見つけるプロセスは試行錯誤です。適切なサイズの整数をランダムに選び、それが素数かどうかをテストします。そうでない場合は、再試行します。
現実の世界では、アルゴリズムを駆動するランダム ジェネレーターは、適切なエントロピーの秘密 (たとえば、128 ビットの真のランダム性) がシードされた決定論的 PRNG です。
あなたの場合、PRNGシードはユーザーシークレットから、または別のキーからも派生させることができます(もちろんシークレットである場合)。派生は、 HKDF、PBKDF2などのソルトされた KDF を使用して実行する必要があります。
どの暗号化ライブラリを使用するかは指定しません。それが何であれ、ランダム性を引き出す方法と 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))
覚えておくべき欠点は次のとおりです。