一般的な暗号化方式のPython実装

20996 ワード

一般的な暗号化方式のPython実装
1.はじめに
我々が言う暗号化方式は,いずれもバイナリ符号化のフォーマットを暗号化しており,Pythonに対応するBytesである.
したがって、Pythonで暗号化操作を行う場合は、Bytesが操作されていることを確認します.そうしないと、エラーが発生します.
文字列およびBytesを互いに変換するには、encode()メソッドおよびdecode()メソッドを使用することができる.次のようになります.
#              utf-8      
enc = 'PyJun'.encode()
print(enc)
print(enc.decode())

# b'PyJun'
# PyJun

注意:2桁の16進数は、通常、1つのバイナリバイトを表示するために使用されます.binasciiモジュールを使用すると、16進数で表示されるバイトを復号化でより一般的な表示に変換できます.
import binascii

info = binascii.b2a_hex(b'PyJun')
print(info)
print(binascii.a2b_hex(info))

# b'50794a756e'
# b'PyJun'

2.URLコード
通常のURLにはASCII文字、すなわち文字、数字、記号しか含まれていません.URL符号化はurlに特殊な文字(漢字など)が現れるのを避けるためのブラウザの符号化方式である.
実はASCIIの範囲外の文字を%の16進数フォーマットに変換します.
例:
from urllib import parse

info = parse.quote("PyJun    ")
print(info)
print(parse.unquote(info))

# PyJun%E5%88%B0%E6%AD%A4%E4%B8%80%E6%B8%B8
# PyJun    

3.Base 64符号化
Base 64は、任意のバイナリデータを64文字で表す方法である.
Base 64符号化は暗号学の基石と呼ぶことができる.任意のバイナリデータをBase 64符号化することができる.すべてのデータを65文字で表すテキストファイルとして符号化することができる.(65文字:A~Z a~z 0~9+/=)符号化後のデータ~=符号化前のデータの4/3は、1/3程度大きくなります.
3.1. げんり
  • は、すべての文字をASCIIコードに変換します.
  • ASCIIコードを8ビットバイナリに変換します.
  • バイナリ3個を1組(3個未満は後で0を補う)の24ビットにまとめ、さらに4組に分割し、各組6ビットとする.
  • 統一は6ビットのバイナリの前に2つの0を補って8ビットを満たす.
  • は0を補ったバイナリを10進数に変換します.
  • Base 64符号化テーブルから10進数対応のBase 64符号化を取得する.

  • 3.2. 説明
  • 変換の際、3つのbyteのデータを、前後して24 bitのバッファに入れ、先に来たbyteが上位を占めます.
  • データが3 byte未満の場合、バッファに残っているbitは0で補完します.そして、毎回6 bitを取り出し、その値に従ってルックアップテーブルを選択して対応する文字を符号化後の出力として選択する.
  • は、すべての入力データ変換が完了するまで継続する.
  • 最後に2つの入力データが残っている場合、符号化結果の後に「=」を1つ追加する.
  • 最後に入力データが1つ残っている場合、符号化結果には「=」が2つ加算される.
  • データが残っていなければ、何も追加しないでください.そうすれば、資料の復元の正確性を保証することができます.

  • 3.3. python使用
    Python内蔵のbase64モジュールはbase 64の符号化を直接行うことができる
    注意:base 64符号化に使用される文字は、ASCIIに含まれる文字か、バイナリデータかです.
    In [1]: import base64
    
    In [2]: base64.b64encode(b'hello world')
    Out[2]: b'aGVsbG8gd29ybGQ='
    
    In [3]: base64.b64decode(b'aGVsbG8gd29ybGQ=')
    Out[3]: b'hello world'
    

    4.MD 5(情報-要約アルゴリズム)
    Message-digest algorithm 5(情報-要約アルゴリズム).よく言われる「MD 5暗号化」は、情報要約アルゴリズムです.
    md 5は、実はアルゴリズムです.文字列、ファイル、または圧縮パケットをmd 5に実行すると、128 bitの固定長の列を生成できます.この串は、基本的に唯一です.
    4.1. 特長
  • 圧縮性:任意の長さのデータで、算出されたMD 5値の長さは固定されている.
  • 計算しやすい:元のデータからMD 5値を計算するのは簡単です.
  • 修正抵抗性:元のデータに対していかなる変更を行っても、1バイトだけ修正しても、得られたMD 5値には大きな違いがあります.
  • 強耐衝突:元のデータとそのMD 5値が既知であり、同じMD 5値を持つデータ(すなわち、データの偽造)を見つけることは非常に困難である.
  • 不可逆性:誰もが異なる指紋を持っていて、この人を見て、彼の指紋などの情報を得ることができて、しかも唯一対応していますが、あなたは指紋を1つしか見ていないので、この人の顔や身分などの情報を見たり読んだりすることはできません.

  • 4.2. python使用
    MD 5モジュールはpython 3から除去されるため、python 3ではhashlibモジュールを用いてmd 5操作が行われる
    import hashlib
    
    #      
    str = '      '
    
    #   md5  
    hl = hashlib.md5()
    
    #       encode
    #     hl.update(str)     : Unicode-objects must be encoded before hashing
    hl.update(str.encode(encoding='utf-8'))
    
    print('MD5     :' + str)
    print('MD5     :' + hl.hexdigest())
    

    実行結果
    MD5     :      
    MD5     :cfca700b9e09cf664f3ae80733274d9f
    

    md 5の長さは、デフォルトでは128 bit、すなわち128個の0と1のバイナリ列である.このような表現は友好的ではない.したがって、バイナリを16進数に変換し、4 bitごとに16進数を表すので、128/4=32を16進数に変換すると32ビットになります.
    どうしてネット上にmd 5が16位なのですか?
    実は16ビットの長さは、32ビットmd 5の値から来ています.32ビットmd 5を上位8ビット、下位8ビットを除いたものです.
    5. AES
    高度な暗号化規格(英語:Advanced Encryption Standard、略称:AES)は、暗号学ではRijndael暗号化法とも呼ばれ、米連邦政府が採用しているブロック暗号化規格である.この基準は従来のDESの代わりに用いられ,多方面にわたって分析され,世界中で広く用いられている.5年間の選考プロセスを経て、高級暗号化規格は米国国家規格と技術研究院(NIST)が2001年11月26日にFIPS PUB 197に発表し、2002年5月26日に有効な規格となった.2006年、高度な暗号化基準は対称鍵暗号化で最も流行しているアルゴリズムの一つとなっている.
    AESは、ソフトウェアおよびハードウェアの両方において高速に復号化することができ、比較的容易であり、わずかなメモリしか必要としない.新しい暗号化基準として、現在、より広い範囲に適用されています.
    5.1. 特長
  • 既知のすべての攻撃に抵抗する.
  • は複数のプラットフォームで速度が速く、符号化がコンパクトである.
  • はデザインが簡単です.

  • AESはパケットパスワードであり、パケットパスワードは明文を1つのグループに分け、各グループの長さは等しく、1つの明文が完全に暗号化されるまでデータのグループを暗号化する.AES規格では、パケット長は128ビットのみであり、すなわち、各パケットは16バイト(各バイト8ビット)である.鍵の長さは、128ビット、192ビット、または256ビットを使用することができる.鍵の長さによって、推奨暗号化ホイール数が異なります.
    一般的によく使われるのは128ビットです
    5.2. Python実現
    PyCryptoはPythonの中で暗号学の面で最も有名なサードパーティのソフトウェアパッケージであり、多くの暗号化アルゴリズムの使用を提供している.残念なことに、その開発作業は2012年に停止した.
    幸いなことに、PyCryptoの代わりに、このプロジェクトのブランチPyCrytodomeがあります.
    Linuxにインストールするには、次のpipコマンドを使用します.
    pip install pycryptodome
    

    インポート:
    import Crypto
    

    Windowsシステムでのインストールは少し異なります.
    pip install pycryptodomex
    

    インポート:
    import Cryptodome
    

    コードの例:
    from Cryptodome.Cipher import AES
    from Cryptodome import Random
    from binascii import b2a_hex  
    
    #       
    data = "I'm PyJun"
    #   key      16(AES-128)、24(AES-192)、 32(AES-256)Bytes   .
    #   AES-128   
    key = b'PyJun'
    key = key[:32] + (32-len(key[:32]))*b' '
    #       AES             
    iv = Random.new().read(AES.block_size)
    
    #   key iv   AES  ,   MODE_CFB  
    mycipher = AES.new(key, AES.MODE_CFB, iv)
    #           16   ,      16   ,      16   
    #  iv(    )         ,    
    ciphertext = iv + mycipher.encrypt(data.encode())
    
    #       key iv    AES  
    mydecrypt = AES.new(key, AES.MODE_CFB, ciphertext[:16])
    #       AES  ,        
    decrypttext = mydecrypt.decrypt(ciphertext[16:])
    
    
    print('  k :', key)
    print('iv :', b2a_hex(ciphertext)[:16])
    print('      :', b2a_hex(ciphertext)[16:])
    print('      :', decrypttext.decode())
    

    実行結果:
      k : b'PyJun                           '
    iv : b'c4b5667e86a7cd00'
          : b'372ea7889776b6c649d11de4c25de9eefe'
          : I'm PyJun
    

    6. RSA
    RSA暗号化アルゴリズムは である.公開鍵暗号化や電子商取引ではRSAが広く用いられている.
    このアルゴリズムは非常に簡単な数論的事実に基づいている:2つの大きな素数を乗算するのは非常に容易であるが、その場合、その積を因数分解することは極めて困難であるため、積を暗号化鍵、すなわち公開鍵として公開することができ、2つの大きな素配列が秘密鍵を合成することができる.公開鍵は公開可能な誰が使用するか、秘密鍵は自分の所有であり、復号のために使用されます.
    6.1. ひたいしょう暗号化
    通常、RSAなどの一般的な方法では、openssl、keytoolsなどのツールを使用して一対の公開鍵ペアを生成し、公開鍵で暗号化されたデータを使用して秘密鍵で復号することができ、逆も同様である(秘密鍵で暗号化されたデータも公開鍵で復号することができる).
    実際の使用では公開鍵は一般に公開者の手に保存され,プライベートで公開されず,公開鍵のみを公開することで,秘密鍵の所有者のみがデータを復号できる方法を実現できる.この暗号化方式は、復号化された鍵を伝達する必要がなく、伝達中に鍵がキャプチャされるリスクがなく、暗号文を解読することはほとんど不可能であるため、セキュリティ係数が高い.
    しかしアルゴリズムの効率は低いため,重要なデータの暗号化によく用いられ,対称と組み合わせて用いられ,非対称暗号化鍵を用いて対称暗号化鍵を暗号化する.
    6.2. Python実現
    まず、rsaモジュールをインストールする必要があります.
    pip install rsa
    

    コードの例
    import rsa 
    
    publickey,privatekey = rsa.newkeys(1024)  #          
    pub = publickey.save_pkcs1()#    
    #        *************
    filepub = open("public.pem",'wb')
    filepub.write(pub)
    filepub.close()
    
    pri = privatekey.save_pkcs1()#    
    #        ***********
    filepri = open('private.pem','wb')
    filepri.write(pri)
    filepri.close()
    
    content = b"PyJun"  #       
    
    #    
    with open('public.pem','rb') as file_pub:
         f_pub = file_pub.read()
         pubkey = rsa.PublicKey.load_pkcs1(f_pub)
    
    #    
    with open('private.pem','rb') as file_pri:
         f_pri =file_pri.read()
         prikey = rsa.PrivateKey.load_pkcs1(f_pri)
    
    #     string
    crypt = rsa.encrypt(content, pubkey)#          
    #  
    de_crypt = rsa.decrypt(crypt,prikey)#      
    
    print(crypt)
    print(de_crypt)
    #    de_crypt content      ,    
    assert content == de_crypt
    

    実行結果:
    b'u\x1fy\\/b\x87O\x9c\x86\x13\x16\xabti\xa4\xf7\xba\xd2\xe0bD\x02\xb9\x7fi\xd5\xeb\xc6\x9a\xc8f\x8c\xd5NoA\x17P\x97\xf8\xfe\xb0%\xd2*\x8fK\x03\x9c\xd0\xb9\x9a\x93@\xbec\xd7\xd5;M\x92\x1bq\xb7`l\x8b\xf9\xb9\xa9\x88\x01\x96\x98\xc1\x17\xcb\x12\xce\xd2\xe7^M\xa5\xbfAq\x94\x0e)\xaf\xc0\xdb\xc9\x7f
    gT\x16\xd5YnND\xd85\xf0}\xc3\xd3\x12ovYp\xfdQ\\` b'PyJun'