Pythonでの暗号化/復号化(AEC-DES,RSA)
概要
Pythonで文字列の暗号化を行う場合は、Python Cryptography Toolkitを利用すると簡単に実装ができます。
Python Cryptography ToolkitはGoogle App Engineでもサポートされています。
http://www.amk.ca/python/code/crypto.html
http://code.google.com/intl/ja/appengine/docs/python/tools/libraries.html#PyCryptoこの記事ではAES-DES,RSAの実装について説明したいと思います。
始めに注意
Google App Engineのサーバに下記のプログラムを配布すれば利用ができますが、
localの場合は最初に
http://www.amk.ca/python/code/crypto.html
からファイルをダウンロード、installする必要があります。
Macでやりましたが、以下の手順でinstallが可能です。fetch http://www.amk.ca/files/python/crypto/pycrypto-2.0.1.tar.gz tar -xzf pycrypto-2.0.1.tar.gz cd pycrypto-2.0.1 python setup.py build sudo python setup.py install
AES-DES
メッセージを特定のkEYで暗号化します。しかしこの方法には以下のようなByte数の制限があります。
KEY : 16,24,32Byteのいずれか
MESSAGE : 16Byteの倍数
以下のサンプルコードでは16ByteのKEYを利用し、unixtimeと文字を結合した文字列を暗号化/復号化しているサンプルになります。サンプルコード
#! /usr/bin/env python # -*- coding: utf-8 -*- import Crypto.Cipher.AES as AES import datetime,time #16,24,32byteの文字列が暗号化KEY CRYPTO_KEY = "16bytes strings" crypto_object = AES.new( CRYPTO_KEY, AES.MODE_ECB ) #unixtimeの取得 d = datetime.datetime.today() utime = int( time.mktime( d.timetuple() ) ) #暗号化できる文字列は16byteの倍数 message = str( utime ) + "string" crypto_message = crypto_object.encrypt( message ) decrypto_message = crypto_object.decrypt( crypto_message ) html = '''Content-Type: text/html; charset=UTF-8 <html> <head> <title>web-pro.appspot.com</title> </head> <body> <table> <tr><th>message </th><td>%s </td></tr> <tr><th>encrypto </th><td>%s </td></tr> <tr><th>decrypto </th><td>%s </td></tr> </table> </body> <html> ''' print html % ( message, crypto_message, decrypto_message )実行結果
message 1297070807string encrypto �7]�Q�˹� decrypto 1297070807string
RSA
RSAによる暗号化/復号化は以下のようになります。
RSAの場合、暗号化する文字列のByte数の制限をプログラムコード中で指定します。
( 例 ) RSA.generate(128, RANDOM.RandomPool().get_bytes ) ← 128bit( 16Byteまで )サンプルコード
#! /usr/bin/env python # -*- coding: utf-8 -*- import Crypto.PublicKey.RSA as RSA import Crypto.Util.randpool as RANDOM import datetime,time #鍵オブジェクト( 鍵を16ByteまでOKとする ) rsa = RSA.generate(128, RANDOM.RandomPool().get_bytes ) #公開鍵 rsa_pub_key = rsa.publickey() #秘密鍵 rsa_private_key = RSA.construct((rsa.n, rsa.e, rsa.d)) #message message = "This is RSA Test" #暗号化 encrypto = rsa_pub_key.encrypt( message, "" ) #復号化 decrypto = rsa_private_key.decrypt( encrypto ) #署名確認 digest = rsa_private_key.sign( message, "" ) digest_flag = rsa_pub_key.verify( message, digest ) html = '''Content-Type: text/html; charset=UTF-8 <html> <head> <title>web-pro.appspot.com</title> </head> <body> <table> <tr><th>message </th><td>%s </td></tr> <tr><th>encrypto </th><td>%s </td></tr> <tr><th>decrypto </th><td>%s </td></tr> <tr><th>digest flag </th><td>%s </td></tr> </table> </body> <html> '''実行結果
message This is RSA Test encrypto ('\x1e\xccC\x99w\xe4\xbf\x05\x0bA\x19\xeaLU\xe1}',) decrypto This is RSA Test digest flag 1