投稿

1月, 2023の投稿を表示しています

RSA鍵を作る

最近暗号系をいろいろ実装してみている中で PKCS #1 の RSA も必要になってきたので実装してみた。中身がわからないと使いにくいタイプ。 RSA は公開鍵暗号という形で秘密鍵、公開鍵の2つの鍵を使う。AESなどの共通鍵暗号とは違うところ。 公開鍵で暗号化、秘密鍵で復号ができるのがひとつめ。 秘密鍵で署名。公開鍵で検証。これが2つめ。  公開鍵暗号共通の特徴ではなくRSAの特徴のようなので注意。 アルゴリズム的にはガロア体と同じようなものを作って2つの状態を行き来してる感じがした。 何に使えるのか。ひととおりバイト列の暗号化などにも使えるが、速さが出ないので署名用途の方が主流で暗号化も一部用途に限定して使う場合が多い。 秘密鍵と公開鍵の中身を見ていく。 RSAは大きい数の因数分解が難しいというところから作られているので2つの素数から鍵を作る。 素数(prime)2つ(pとq)を決める。2048ビットのRSAだと1024ビットくらいの素数を2つ。今なら3072ビットくらいが最低ラインになってきているので1536ビットくらいの素数を2つ。 Java で作るのでいろいろ省略できるところは省略する。 乱数はjava.math.SecureRandom っぽいところから。安全かどうかは不明。他の要素があればいろいろ混ぜるとより安全かも。普通のRandomは安全ではない。 SecureRandom srnd = SecureRandom.getInstanceStorong(); BigInteger p = BigInteger.probablePrime( len / 2, srnd ); BigInteger q = BigInteger.probablePrime( len / 2, srnd ); これで素数2つを作ってくれるのでおまかせ。素数ではない場合もあるらしい。 modulus 素数2つを掛けたもの 変数名は n など。 BigInteger n = p.multiply(q); // n = p * q nをpとqに素因数分解するのが難しい。 次はeとdという指数(exponent)を決めていく。 eは公開指数(public exponent)、dは秘密指数(private exponent)。 e * d = 1 mod (p - 1)(q - 1)