PythonはPycrypttoライブラリを使ってRSA暗号化を行う方法を詳しく説明します。


パスワードと通信
暗号技術は歴史の長い技術です。情報の伝播は暗号化と復号から切り離せない。暗号技術の用途は主に二つの方面から由来しています。
情報伝播には、送信者、受信者、盗聴者の3つの役割が一般的にある。送信者Masterが受信者Ghostに手紙を書こうとすると、信じたくない内容が他の人に見られますので、Masterは先に手紙を暗号化しなければなりません。Ghostは手紙を受け取ってから解読できます。このように他の人は盗聴しても暗号文を盗むことができません。第二に、盗聴者が翻訳内容ではなく、マスターズを偽造してGhostにメッセージを送る場合、マスターズはメッセージを送る前に機密内容に署名しなければならない。
パスワード技術
暗号化および通信のために、多くの公開アルゴリズムが発明された。対称と非対称アルゴリズムなど。一般的な暗号化方式はRSA、AESなどのアルゴリズムがあります。暗号化アルゴリズムを選択するには、一般的なアルゴリズムを使用することが常識です。これらのアルゴリズムは実践的に検証されている一方で、翻訳の難しさや解読条件について時間が予測されています。どの暗号化アルゴリズムに対しても、時間的な投入によって解読できます。
Pythonパスワードライブラリ--Pycryptto
Pythonの良好な生態は、暗号解読技術に対して成熟した第三者ライブラリがあります。有名なM 2 CryptとPycryptは、前者は非常に使いやすいですが、インストールには頭が痛く、システムによってはソフトのバージョンに依存しています。後者は比較的にpipを使ってインストールすればいいです。
インストール

pip install pycrypto
RSAパスワードアルゴリズムと署名
RSAは公開鍵暗号アルゴリズムであり、RSAの暗号文はコード本文の数字のE乗にmod Nを求める結果である。つまり、明文と自分をE回乗算して、その結果をNで割って余りを求めるということです。残りは暗号文です。RSAは簡潔な暗号化アルゴリズムである。EとNの組み合わせが公開鍵です。
RSAの解読に対して、すなわち暗号文の数字のD乗はmod Nを求めても良いです。つまり、暗号文と自分でD乗をして、結果に対してNを除いて余りを求めると明文が得られます。DとNの組み合わせは秘密鍵です。
アルゴリズムの暗号化と解読はまだ簡単ですが、公開鍵と秘密鍵の生成アルゴリズムは任意ではありません。本論文は、秘密鍵ペアを生成するアルゴリズムを使用して、一時的に無視することにある。Pycryptを使って秘密鍵を生成するのは簡単です。私たちはそれぞれMasterとGhostのペアに自分の秘密鍵を生成します。

from Crypto import Random
from Crypto.Hash import SHA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5
from Crypto.PublicKey import RSA

#        
random_generator = Random.new().read
# rsa      
rsa = RSA.generate(1024, random_generator)

# master       
private_pem = rsa.exportKey()

with open('master-private.pem', 'w') as f:
  f.write(private_pem)

public_pem = rsa.publickey().exportKey()
with open('master-public.pem', 'w') as f:
  f.write(public_pem)

# ghost       
private_pem = rsa.exportKey()
with open('master-private.pem', 'w') as f:
  f.write(private_pem)

public_pem = rsa.publickey().exportKey()
with open('master-public.pem', 'w') as f:
  f.write(public_pem)

生成された秘密鍵と公開鍵は、概ねこうである。

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDR4Wq9l44lw/thTPyFmSi2hII92EPh90yGXQNL5e7zJPD16j6Q
tr+tIPNSQaVrnmNwrtqyEC2x4Meyp3tdCWPYUF11r2GgDgxKfUByetNG4XqJeUKk
kJ6D6C706mTf/2zsm8KFoNYCYPX1GhvpiTOikHcNlHLCnOD7jbMAovJg/QIDAQAB
AoGBAIz8V6+0NxC3bg4WoSs9j1PL/5F7zV3lucoogSZi9vjuP89x40Vi/a9XCxye
bHi2lSYEz3P92jQ7QuqIBx6gSCi3p2HLjD5LyQeSSMbPe8KSlf52dBUaPthbBceA
IJSBDrE8MKGpulTQKAJ7K3zQUOP2ZZgcKxq2jcQgS6iTENIBAkEA5r7emvwuL0Ob
Maav4o1Ovb5c6OL7bSm1tuLPSKl05WuNYfE6LkqiwOOn5lPvsqhwyI1dJeywVeQz
E+PvcTUR7QJBAOjZ8PxnP5T14fuhbfko4d24Ev+iiTBdq3pMXWvobEFL1ljV6aYE
2JAiMjO/Fzd1WgZhWPa3P+diyTs9mART6VECQQC0LeEXdsn9oDYEbFu1dZBB++8C
75NTJ5m8iJlB7QjZyMUq8Ln0wdUa9+n4ohxvDraa9EADSDJdr4bvBjLH3J/1AkBr
9QfO7kvDU5DXqoujVnoJ4xsj3IbAnt0vEZLKwfLW/0M84si2SU7i3IfsB+/KraT0
ilPF50ZAkEN+LNt7PjBRAkAHBBPME7IbFqxi5Cc/6R12DOMiJbOLDTS12b1J1cwG
p8WMIERsvwWdJw+4NdqjbJcjzeGrXhDBi//JU902TAwy
-----END RSA PRIVATE KEY-----

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDR4Wq9l44lw/thTPyFmSi2hII9
2EPh90yGXQNL5e7zJPD16j6Qtr+tIPNSQaVrnmNwrtqyEC2x4Meyp3tdCWPYUF11
r2GgDgxKfUByetNG4XqJeUKkkJ6D6C706mTf/2zsm8KFoNYCYPX1GhvpiTOikHcN
lHLCnOD7jbMAovJg/QIDAQAB
-----END PUBLIC KEY-----

暗号化と復号
通常通信の場合、送信者は、受信者の公開鍵を用いて暗号化され、受信者は、受信者の秘密鍵を用いて復号される。
簡単に言えば、マスターはGhostに通信して、暗号化された内容を必要とします。Ghostは秘密鍵ペアを生成します。Ghostの公開鍵ghost-public.pemと秘密鍵ghost-prvate.pem。Ghostは公開鍵を送信者に公開し、誰でも暗号化することができます。そしてMasterはghost-public.pemを使って暗号化し、その後Ghostにコンテンツを送り、Ghostはghost-prvate.pemを使って解読します。
1.暗号化(encrypt)

# Master  Ghost        rsa   

In [12]: message = 'hello ghost, this is a plian text'
In [13]: with open('ghost-public.pem') as f:
  ....:   key = f.read()
  ....:   rsakey = RSA.importKey(key)
  ....:   cipher = Cipher_pkcs1_v1_5.new(rsakey)
  ....:   cipher_text = base64.b64encode(cipher.encrypt(message))
  ....:   print cipher_text
  ....:


HYQPGB+axWCbPp7PPGNTJEAhVPW0TX5ftvUN2v40ChBLB1pS+PVM3YGT5vfcsvmPZhW8NKVSBp8FwjLUnMn6yXP1O36NaunUzyHwI+cpjlkTwZs3DfCY/32EzeuKuJABin1FHBYUMTOKtHy+eEDOuaJTnZTC7ZBkdha+J88HXSc=

cipher_textとは、Masterが暗号化されたらGhostに送る暗号文です。
2.復号(decrypt)

# Ghost            rsa    

In [14]: with open('ghost-private.pem') as f:
  ....:   key = f.read()
  ....:   rsakey = RSA.importKey(key)
  ....:   cipher = Cipher_pkcs1_v1_5.new(rsakey)
  ....:   text = cipher.decrypt(base64.b64decode(encrypt_text), random_generator)
  ....:
In [15]: print text
hello ghost, this is a plian text
In [16]: assert text == message, 'decrypt falied'

このようにGhostはマスターの送った内容を見ることができます。もちろん、Ghostがマスターにメッセージを送るには、マスターが先にその公開鍵をGhostに渡す必要があります。後者は公開鍵を使って暗号化し、Masterに送ります。最後にマスターは自分の秘密鍵を使って解読します。
署名と検札
もちろん盗聴者に対しては、マスターズを偽造してGhostに送ることもあります。このためにデジタル署名があります。つまりマスターがGhostにメッセージを送る時、先にメッセージに署名し、自分の身分を表明します。そしてこのサインは偽造できません。具体的なプロセスは、マスターが自分の秘密鍵を使ってコンテンツに署名し、その後、Ghostがマスターの公開鍵を使って検証します。
署名する

# Master               
In [17]: with open('master-private.pem') as f:
  ....:    key = f.read()
  ....:    rsakey = RSA.importKey(key)
  ....:    signer = Signature_pkcs1_v1_5.new(rsakey)
  ....:    digest = SHA.new()
  ....:    digest.update(message)
  ....:    sign = signer.sign(digest)
  ....:    signature = base64.b64encode(sign)
In [18]: print signature
jVUcAYfgF5Pwlpgrct3IlCX7KezWqNI5tD5OIFTrfCOQgfyCrOkN+/gRLsMiSDOHhFPj2LnfY4Cr5u4eG2IiH8+uSF5z4gUX48AqCQlqiOTLk2EGvyp+w+iYo2Bso1MUi424Ebkx7SnuJwLiPqNzIBLfEZLA3ov69aDArh6hQiw=

検札する

In [22]: with open('master-public.pem') as f:
  ....:   key = f.read()
  ....:   rsakey = RSA.importKey(key)
  ....:   verifier = Signature_pkcs1_v1_5.new(rsakey)
  ....:   digest = SHA.new()
  ....:   # Assumes the data is base64 encoded to begin with
  ....:   digest.update(message)
  ....:   is_verify = signer.verify(digest, base64.b64decode(signature))
  ....:   print is_verify
  ....:
True

締め括りをつける
Pycryptは比較的完全な暗号化アルゴリズムを提供しています。RSAは暗号化と復号に広く使われています。デジタル署名通信の分野もあります。Publick/Private秘密鍵アルゴリズムを使用して、暗号化は主に相手の公開鍵を使って、自分の秘密鍵を復号します。署名は自分の秘密鍵を使って、相手の公開鍵を検証します。
  • 暗号解読:公開鍵暗号化、秘密鍵復号
  • 署名検証:秘密鍵署名、公開鍵検証
  • 暗号化の秘密も署名の検証も同じ秘密鍵ペアを使用します。