概要
僕は相も変わらずに不毛なNEET生活を満喫しております。このNEET生活が出来ることをまことに嬉しく思います。この調子で実りのないNEET生活を満喫したいとも思っています。私は無病息災なのだが、部屋で本を読んだり、パソコンヲカタカタしていることにもそろそろ飽きてきた…。外に出たい…。そう強く感じるが外に一切の用事がなく外出が出来ないのであった…。 このブログでは何となくRSA実装した後にpythonのCryptoという便利ツールを使ってライブラリは便利だな~そのようなことを感じる為のブログになります。
RSAとは
RSA暗号とは、桁数が大きい合成数の素因数分解問題が困難であることを安全性の根拠とした公開鍵暗号の一つである。暗号とデジタル署名を実現できる方式として最初に公開されたものである。理論や数式が知りたい場合はこちらを参考にして下さい!!!
pythonを使って暗号化、復号を行う
# -*- coding: utf-8 -*- message = "NEET".encode("utf-8") message_int = int.from_bytes(message, byteorder='big') print("文章:{}".format(message)) print("平文:{}".format(message_int)) # メッセージは、modulusより小さい値でなければならない。 modulus = 3243485389 publicExponent = 65537 privateExponent = 2834145457 # 暗号化 # pow(x,y,m) で x^y mod m が計算できる ciphertext = pow(message_int, publicExponent, modulus) print("暗号化:{}".format(ciphertext)) # 復号 # pow(x,y,m) で x^y mod m が計算できる message2 = pow(ciphertext, privateExponent, modulus) print("復号:{}".format(message2))
$python3 rsa_hand.py 文章:b'NEET' 平文:1313162580 暗号化:2289434900 復号:1313162580
できたね!!!♥
Cryptoについて
pythonのパッケージであるCrypto
は、SHA256とRIPEMD160などの安全なハッシュ関数と、さまざまな暗号化アルゴリズム(AES、DES、RSA、ElGamalなど)のパッケージです。またこのパッケージは、新しいモジュールの追加を容易にするように構成されているので新しい暗号が出来たらどしどしプルリク投げてね~みたいなことを書いていました。
インストール
$sudo pip3 install Crypto
実装
# -*- coding: utf-8 -*- import Crypto.PublicKey.RSA import Crypto.Util.randpool import sys pool = Crypto.Util.randpool.RandomPool() # RSAオブジェクトをランダムな鍵で生成する # 2048bitまでを暗号化できるようにする rsa = Crypto.PublicKey.RSA.generate(2048, pool.get_bytes) # 公開鍵を取得する pub_rsa = rsa.publickey() # RSAオブジェクトをタプルから生成する # rsa.nが公開鍵、rsa.dが秘密鍵と思う priv_rsa = Crypto.PublicKey.RSA.construct((rsa.n, rsa.e, rsa.d)) # 適当に文字列を生成しておく message = "Hello @nwiizo".encode('utf-8') # 暗号化する enc = pub_rsa.encrypt(message, "") # 復号する dec = priv_rsa.decrypt(enc) print ("秘密鍵: n={}, e={}, d={}, p={}, q={}, u={}".format(rsa.n, rsa.e, rsa.d, rsa.p, rsa.q, rsa.u)) print ("公開鍵: n={}, e={}".format(pub_rsa.n, pub_rsa.e)) print ("元の文章:{}".format(message)) print ("暗号化:{}".format(enc)) print ("復号:{}".format(dec)) # 署名する text = (message) signature = priv_rsa.sign(message, "") # 文字列が変わってないか調べる print("正しいかどうか".format(pub_rsa.verify(text, signature)))
出力
秘密鍵: n=25401972993584597055873809066251287941109210512241917400799861109804670436894398744562031720678325059603387247215804992152593257403140392987012933111766397693991919867957453259798319579553354667000771758720443206878279740163664941908284664282169416929408496652520716977934430014986983927382320595831128004399967528795033407508571606472358664109387374305748032835001766745998660630336948870671023220811060233795582221142764634593118586133984456690485603618146529942889041956480699686686582827669080696788442892728998280982895722501770092596436150386935426727505394641659132916248981141380300406214786683672284035185341, e=65537, d=18906615204450357199573806131539002006185302647003196498063939836659627679650760278331192231914308224093163045790007960575115530202294661481506688805695303616510243972703917063028552279949236115501634887447159607371646664410079988424008081526770251741758351133150862161323581514275143643953525738804745303059498963843811081753103845632271368197587942144980736617020115534163030384704736316066289018505079353210690704231896473657490226727989682488764913741208838900568518041589419976942444130503917748879372731266726299073112553972405677127488094053953532438716055904232048230449223022706930311685838098630512718185301, p=143678153925580659957979433494024065647585769219095816431410582475656640940756092603521526341430122163764659607786191927084571641446152791716949044933272980937893842574755022369928057821636191832768164089133532714141630274600879164473610808169347898578707655595083108501662504089664620259247067406666007662339, q=176797740641501896212660819750499582366636886113747374058428658604032253149154012491405763725511011786207018406874152006304684471991350880744788732224231458628837962167577395022963612160012259351881073808329836475675565613471702988858186885722911575884719012229905096315130006134931654321951976708679344653119, u=119012556768809091324589005370932984333473914845074287024609689000854106512536655064505450018094102617325195459084759115685760177776494569751253174440876992424614343535706333551564329876782656578286742594687515538112296532286525311592440459941763966365470557032157177526225391949653808077762356892968401515821 公開鍵: n=25401972993584597055873809066251287941109210512241917400799861109804670436894398744562031720678325059603387247215804992152593257403140392987012933111766397693991919867957453259798319579553354667000771758720443206878279740163664941908284664282169416929408496652520716977934430014986983927382320595831128004399967528795033407508571606472358664109387374305748032835001766745998660630336948870671023220811060233795582221142764634593118586133984456690485603618146529942889041956480699686686582827669080696788442892728998280982895722501770092596436150386935426727505394641659132916248981141380300406214786683672284035185341, e=65537 元の文章:b'Hello @nwiizo' 暗号化:(b"\x87RUl_\x82\x1dg0\xe3\xc0\x83\xb5#\x89\xea\x92\xa8\xe0\xe5t\x9a\x1c\xacq\x88\xf1\x85\x9a\xe4d[\xd4\xf9\x9d\xe5\x8eG\xf3\xcff93B\x85\x12Nl\xf7<vH\xc6\xdcG\xd6\xa7t\xb1d\xc7f\xbeQr\xc0V\xa7\xd2y\xad\xbe\x049\xc1\xe6\x97\x1a[a\x86\x83*\xe5\x8bBC\x97r\x96\x8f\xb6'\xd6\xf0\xa7\xff$\xdc\xc1\xee#\xad5q\xfc\xfb\x07\xbc=x\x9e\x11H\x0ei{b:-\xc8\x06\x97\xc0\xcc;\xc3\xd4E\x83K\xb6\x98\x0e\xa82\xe1\xa3+\x04\xb1\x9bS\xd1\xae\xc4\xc1]fZ\xef\xa3\x02\xcf\\i\x15\xe8\x87} \x90J\xffv\xf7\xdb\xb3C\x08\x07bM\xd9\xca\x0f\x1b\x00T\x91\x11l\xea\xe1\r\xdf\t\xfc\xd3f\xa5\x87\xb7!E0\x9c\x87tY\n\x08,\xdb\x87q \xda\xd4\xa4RVq\x12\xc9\xc6P\xfa!\x02\x02\xee.\xc5\xa5\xb7\xc5\xe66\xaf\x92\xdd\x92\x82\xda_ti[K&w4u\x9b*\xa9\xe0Q\xae\x07N\n8\xd4J",) 復号:b'Hello @nwiizo'
楽だね!!!やったー!!!♥
環境
- Ubuntu 16.04.1 LTS
- python3
- crypto-1.4.1
- OpenSSL 1.0.2g 1 Mar 2016
最後に
遊んでるだけなので適当に参考にして 春休みで生活リズムがぐちゃぐちゃなので正常に戻したいです。いい方法募集しています。
参考
暗号技術入門 第3版 秘密の国のアリス
2017年から30年後の君へ 【素数の年】 - じゃあ、おうちで学べる
OpenSSLコマンドの備忘録 - Qiita
4. 組み込み型 — Python 3.5.2 ドキュメント
PyCrypto API Documentation