https://milestone-of-se.nesuke.com/nw-basic/tls/rsa-summary/
# cat rsa.pl use Math::BigInt; #data my $data = Math::BigInt->new("508"); print "data: ".$data."\n"; # encrypt # koukaikagi 223, 1357 my $pubkey1 = 223; my $pubkey2 = 1357; my $crypt = ($data ** $pubkey1) % $pubkey2; print "crypted data: ".$crypt."\n"; #decrypt #himitukagi 103 my $privkey = 103; $decrypt = ($crypt ** $privkey) % $pubkey2; print "decrypted data: ".$decrypt."\n";
実行結果
# perl rsa.pl data: 508 crypted data: 1319 decrypted data: 508元のデータは 508
公開鍵となる数字は2つのペアで 223と1357である。
暗号化されたデータは、元のデータを223乗して、それを1357で割った余りとして作成し
この例ではその値は 1319である。
秘密鍵の値は103である。
復号は、1319を103乗して1357で割った余りとして求め、
その値は508であり、元のデータと一致する。
結果だけ見ると3~4桁の数字であるが、
計算途中で「508の223乗」というとんでもない計算があり、
280桁くらいになるので BigIntを使っている。
しかし実際の暗号化においては、508などという数値どころではない
文字列や画像、音声などを暗号化しているのだから
とてつもない量の計算がされている。
そのために暗号化専用のチップなどが使われたりしているのだ。
注目すべきは下記の記述である。
「メッセージ m を e 乗 (公開鍵で暗号化) したものに対しては d 乗 (秘密鍵で復号) することで元の m に戻りますし、
メッセージ m を d 乗 (秘密鍵で暗号化) したものに対しては e 乗 (公開鍵で復号) することで元の m に戻るのです。」
これがよく話題になる、「電子署名のことを秘密鍵で暗号化するというのは間違い」
のことである。
この人は、「別に署名を秘密鍵で暗号化するといってもいいじゃないか。」
という旨のことを言っている。
私もそう思う。
では、署名と検証もやってみよう。
# cat sign.pl use Math::BigInt; #data my $data = Math::BigInt->new("508"); print "data: ".$data."\n"; # encrypt # koukaikagi 223, 1357 #himitukagi 103 my $pubkey1 = 223; my $pubkey2 = 1357; my $privkey = 103; my $sign = ($data ** $privkey) % $pubkey2; print "signed data: ".$sign."\n"; #verify $verified = ($sign ** $pubkey1) % $pubkey2; print "verified data: ".$verified."\n";さっきの暗号化の計算と同じことを、
暗号化時(署名時)に103乗し、復号時(検証時)に223乗、つまり逆にしている。
逆にしても、元の値に戻る。
# perl sign.pl data: 508 signed data: 315 verified data: 508当然、公開鍵と秘密鍵というのはどんな数字でもいいわけではなく、
上記のような計算が成り立つような数字を選ぶわけであるが、
「署名を秘密鍵で暗号化すると言ってはいけない」と怒ることはないんだなと、
ようやく安心できた。
python版
# cat rsa.py data=508 pub1=223 pub2=1357 priv=103 print("data:"+str(data)) crypted=(data ** pub1) % pub2 print("crypted:"+str(crypted)) decrypted=(crypted ** priv) % pub2 print("decrypted:"+str(decrypted)) signed=(data ** priv) % pub2 print("signed:"+str(signed)) verified=(signed ** pub1) % pub2 print("verified:"+str(verified)) # python rsa.py data:508 crypted:1319 decrypted:508 signed:315 verified:508BigIntとかいらない。