今回はRSA暗号について
考えてみることにしました。
解説動画はこちら
さてさて
RSAッて良く分からないので
Wikiで調べてみることにしました。
うん・・・・・
はい良くわかりませんです!!!
というわけで
サンプルコードを作ってみました。
使う際は平文として暗号化したい
文字列を定義しておきます。
早速使っていきましょう。
暗号化するところと
復号化するところのコードです。
素数P,Qや
鍵N,Dは毎回変わってしまいます。
公開鍵Nと秘密鍵Dがあれば
暗号を解読することができます。
暇な方は上記の鍵と暗号文から
復号してみてくださいね。
人類を平和にする
「あいことば」を暗号にしてみましたよ
解読面倒な方は
動画見て下さいねーー
このサンプルコードでは
およそ20桁ほどの秘密鍵になりますんで
9千京回ほどブルートフォースすれば
暗号解読できるかもしれません!!!!
鼻血出せば解けるかもしれませんねえ
そんなアニメが有るとか無いとか
自分ならやらないっすねーー
今回はここまででーす
それでは。
考えてみることにしました。
解説動画はこちら
さてさて
RSAッて良く分からないので
Wikiで調べてみることにしました。
RSA暗号とは、桁数が大きい合成数の素因数分解問題が
困難であることを安全性の根拠とした公開鍵暗号の一つ
鍵生成、暗号化、復号の3つのアルゴリズムで定義される
うん・・・・・
RSA暗号は次のような方式である
鍵のペア(公開鍵と秘密鍵)を作成して公開鍵を公開する
まず、適当な正整数 E を選択する
まず、適当な正整数 E を選択する
また、大きな2つの素数の組み P,Q を生成し
それらの積(N=PQ)を求めて、組みE,N を
平文の暗号化に使用する鍵(公開鍵)とする
それらの積(N=PQ)を求めて、組みE,N を
平文の暗号化に使用する鍵(公開鍵)とする
2つの素数P,Qは秘密に保管し
暗号文の復号に使用する鍵(秘密鍵)D の生成にも使用する
暗号文の復号に使用する鍵(秘密鍵)D の生成にも使用する
暗号化(平文 M から暗号文 C を作成する):
復号(暗号文 C から元の平文 M を得る):
暗号化(E 乗)は公開鍵 E,N があれば容易に計算でき
復号(D 乗)も容易に計算できる
復号(D 乗)も容易に計算できる
しかし、秘密鍵 D を知らずに
解読(法 N の下で E 乗根を計算)するのは
解読(法 N の下で E 乗根を計算)するのは
「N の素因数を知らないと難しい」と考えられている
つまり
「秘密鍵を用いずに暗号文から平文を得ることは難しい」
と信じられている
「秘密鍵を用いずに暗号文から平文を得ることは難しい」
と信じられている
これがRSA暗号の安全性の根拠である
はい良くわかりませんです!!!
というわけで
サンプルコードを作ってみました。
# RSA暗号の例 import random import fractions import sympy import warnings warnings.filterwarnings('ignore') # 乱数生成 def _random(): digit = 10 return random.randrange(10**(digit - 1),10**digit) # 最小公倍数 def _lcm(p , q): return (p * q) // fractions.gcd(p, q) # 拡張ユークリッド def _euclid(x,y): c0, c1 = x, y a0, a1 = 1, 0 b0, b1 = 0, 1 while c1 != 0: m = c0 % c1 q = c0 // c1 c0, c1 = c1, m a0, a1 = a1, (a0 - q * a1) b0, b1 = b1, (b0 - q * b1) return c0, a0, b0 # キー生成 def generate_key(p = 0,q = 0,e = 0,d = 0,n = 0,l = 0): if p == 0: while True: p = _random() if sympy.isprime(p):break _p = p if q == 0: while True: q = _random() if sympy.isprime(q) and p != q:break _q = q if n == 0: n = p * q _n = n if l == 0: l = _lcm(p - 1, q - 1) _l = l if e == 0: while True: i = random.randint(2,l) if fractions.gcd(i, l) == 1: e = i break _e = e if d == 0: _c, a, _b = _euclid(e, l) d = a % l _d = d return _e,_d,_n,_p,_q,_l # 暗号化 def encrypt(_e,_n,plaintext): st,ciphertext = "",[] for i in map((lambda x: pow(ord(x), _e,_n)),list(plaintext)): ciphertext.append(i) st += str(i) return st,ciphertext # 復号化 def decrypt(_d,_n,ciphertext): cip , st = [] , "" for i in list(ciphertext): tmp = chr(pow(i, _d,_n)) cip.append(tmp) st += str(tmp) return st
使う際は平文として暗号化したい
文字列を定義しておきます。
plain_text = '文字列を入力'
早速使っていきましょう。
暗号化するところと
復号化するところのコードです。
# 初期化 ciphertext = [] _e = _d = _n = _p = _q = _l = 0 # キー生成 _e,_d,_n,_p,_q,_l = generate_key(0,0,65537) # 暗号化 e_text , ciphertext = encrypt(_e,_n,plain_text) # 復号化 d_text = decrypt(_d,_n,ciphertext) print('素数 p : {0}'.format(_p)) print('素数 q : {0}'.format(_q)) print('l : {0}'.format(_l)) print('公開鍵 e : {0}'.format(_e)) print('公開鍵 n : {0}'.format(_n)) print('秘密鍵 d : {0}'.format(_d)) print() print('暗号文(String) : {0}'.format(e_text)) print() print('暗号文(List) : {0}'.format(ciphertext))
素数 p : 9558530557
素数 q : 5377612577
l : 12850518531506468064
公開鍵 e : 65537
公開鍵 n : 51402074140962015389
秘密鍵 d : 104902992421928993
暗号文(String) : 502447033995121916661752375033108949410513472439923007515854175237503310894941051347243992300751585434094647152221189902182494137669912247793511588278946816434351158827894681643422454674385942603378
暗号文(List) : [50244703399512191666, 17523750331089494105, 13472439923007515854, 17523750331089494105, 13472439923007515854, 34094647152221189902, 18249413766991224779, 3511588278946816434, 3511588278946816434, 22454674385942603378]
素数P,Qや
鍵N,Dは毎回変わってしまいます。
公開鍵Nと秘密鍵Dがあれば
暗号を解読することができます。
暇な方は上記の鍵と暗号文から
復号してみてくださいね。
人類を平和にする
「あいことば」を暗号にしてみましたよ
解読面倒な方は
動画見て下さいねーー
このサンプルコードでは
およそ20桁ほどの秘密鍵になりますんで
9千京回ほどブルートフォースすれば
暗号解読できるかもしれません!!!!
鼻血出せば解けるかもしれませんねえ
そんなアニメが有るとか無いとか
自分ならやらないっすねーー
今回はここまででーす
それでは。