Cryptography-with-python-quick-guide

提供:Dev Guides
移動先:案内検索

Pythonによる暗号化-概要

暗号化は、コード化されたメッセージを介した2人のユーザー間のコミュニケーションの技術です。 暗号化の科学は、ある当事者から別の当事者に転送された機密メッセージにセキュリティを提供するという基本的な動機とともに現れました。

暗号化とは、情報セキュリティで認められているように、プライバシーと秘密を導入するためにメッセージを隠す技術と科学として定義されています。

暗号化の用語

暗号で頻繁に使用される用語はここで説明されています-

プレーンテキスト

プレーンテキストメッセージは、読みやすく、すべてのユーザーが理解できるテキストです。 プレーンテキストは、暗号化を受けるメッセージです。

暗号文

暗号テキストは、プレーンテキストに暗号化を適用した後に取得されるメッセージです。

暗号化

プレーンテキストを暗号化テキストに変換するプロセスは、暗号化と呼ばれます。 エンコードとも呼ばれます。

復号化

暗号テキストをプレーンテキストに変換するプロセスは、復号化と呼ばれます。 デコードとも呼ばれます。

以下の図は、暗号化の完全なプロセスの図を示しています-

暗号化の用語

現代暗号の特徴

現代の暗号化の基本的な特徴は次のとおりです-

  • ビットシーケンスで動作します。
  • 数学的アルゴリズムを使用して情報を保護します。
  • プライバシーを実現するには、安全な通信チャネルに関心のある当事者が必要です。

二重強度暗号化

倍強度暗号化は、多重暗号化とも呼ばれ、既に暗号化されたテキストを同じまたは異なるアルゴリズム/パターンで1回以上暗号化するプロセスです。

二重強度暗号化の他の名前には、カスケード暗号化またはカスケード暗号化が含まれます。

二重強度暗号化のレベル

二重強度暗号化には、ここで説明するさまざまなレベルの暗号化が含まれます-

暗号化の最初のレイヤー

暗号テキストは、ハッシュアルゴリズムと対称キーを使用して、元の読み取り可能なメッセージから生成されます。 後の対称キーは、非対称キーを使用して暗号化されます。 このパターンの最良の例は、暗号テキストのハッシュダイジェストをカプセルに結合することです。 受信者は最初にダイジェストを計算し、後でテキストが改ざんされていないことを確認するためにテキストを解読します。

暗号化の第2層

暗号化の第2層は、同じまたは異なるアルゴリズムを使用して暗号化テキストにもう1つの層を追加するプロセスです。 通常、32ビット文字の長い対称パスワードが同じパスワードに使用されます。

暗号化の第3層

このプロセスでは、暗号化されたカプセルがSSL/TLS接続を介して通信パートナーに送信されます。

次の図は、二重暗号化プロセスを絵で示しています-

強度暗号化

ハイブリッド暗号

ハイブリッド暗号は、各暗号の利点を含めることにより、異なるタイプの複数の暗号を一緒に使用するプロセスです。 通常、対称暗号用のランダムな秘密鍵を生成し、非対称鍵暗号化を介してこの鍵を暗号化するために使用される一般的なアプローチが1つあります。

このパターンにより、元のメッセージ自体は対称暗号を使用して暗号化され、次に秘密鍵を使用して暗号化されます。 メッセージを受信した受信者は、まず自分の秘密鍵を使用して秘密鍵を使用してメッセージを復号化し、次に指定された鍵を使用してメッセージを復号化します。

Pythonの概要とインストール

Pythonは、高レベルで、解釈された、インタラクティブでオブジェクト指向のオープンソースのスクリプト言語です。 読みやすいように設計されています。 Python言語の構文は理解しやすく、英語のキーワードを頻繁に使用します。

Python言語の機能

Pythonは次の主要な機能を提供します-

解釈済み

Pythonは、実行時にインタープリターを使用して処理されます。 実行前にプログラムをコンパイルする必要はありません。 これは、PERLおよびPHPに似ています。

オブジェクト指向

Pythonは、オブジェクト指向のスタイルとデザインパターンに従います。 カプセル化やポリモーフィズムなどのさまざまな機能を備えたクラス定義が含まれています。

Python言語のキーポイント

Pythonプログラミング言語のキーポイントは次のとおりです-

  • 機能的および構造的なプログラミングとメソッド、およびオブジェクト指向プログラミングメソッドが含まれています。
  • スクリプト言語またはプログラミング言語として使用できます。
  • 自動ガベージコレクションが含まれます。
  • 高レベルの動的データ型が含まれており、さまざまな動的型チェックをサポートしています。
  • Pythonには、C、C ++、およびJavaなどの言語との統合機能が含まれています。

Python言語のダウンロードリンクは次のとおりです-https://www.python.org/downloads/[www.python.org/downloads]Windows、MacOS、Linuxディストリビューションなどのさまざまなオペレーティングシステム用のパッケージが含まれています。

Pythonダウンロード

Python文字列

文字列の基本的な宣言は以下に示されています-

str = 'Hello World!'

Pythonリスト

Pythonのリストは、コンマで区切られ、角括弧([])で囲まれた複合データ型として宣言できます。

list = [ 'abcd', 786 , 2.23, 'john', 70.2 ]
tinylist = [123, 'john']

Pythonタプル

タプルは、コンマで区切られた多数の値で構成されるPythonの動的データ型です。 タプルは括弧で囲まれています。

tinytuple = (123, 'john')

Python辞書

Python辞書は、ハッシュテーブルの一種です。 辞書キーは、ほとんどすべてのPythonのデータ型であり、通常は数値または文字列です。

tinydict = {'name': 'omkar','code':6734, 'dept': 'sales'}

暗号化パッケージ

Pythonには、暗号化のレシピとプリミティブを提供する暗号化と呼ばれるパッケージが含まれています。 Python 2.7、Python 3.4+、およびPyPy 5.3+をサポートしています。 暗号化パッケージの基本的なインストールは、次のコマンドを介して達成されます-

pip install cryptography

対称暗号メッセージダイジェスト、*キー派生関数などの一般的な暗号化アルゴリズムに対する高レベルのレシピと低レベルのインターフェースの両方を備えたさまざまなパッケージがあります。

このチュートリアルでは、暗号化アルゴリズムの実装にPythonのさまざまなパッケージを使用します。

Pythonでの暗号化-逆暗号

前の章では、ローカルコンピューターへのPythonのインストールの概要を説明しました。 この章では、逆暗号とそのコーディングについて詳しく学習します。

逆暗号のアルゴリズム

逆暗号のアルゴリズムは、次の機能を保持しています-

  • Reverse Cipherは、プレーンテキストの文字列を反転するパターンを使用して、暗号テキストとして変換します。
  • 暗号化と復号化のプロセスは同じです。
  • 暗号化テキストを復号化するには、ユーザーは暗号化テキストを逆にしてプレーンテキストを取得するだけです。

欠点

逆暗号の主な欠点は、非常に弱いことです。 ハッカーは暗号文を簡単に解読して元のメッセージを取得できます。 したがって、リバース暗号は、安全な通信チャネルを維持するための適切なオプションとは見なされません。

欠点

ステートメント*これは逆暗号を説明するプログラム*が逆暗号アルゴリズムで実装される例について考えてみましょう。 次のPythonコードは、アルゴリズムを使用して出力を取得します。

message = 'This is program to explain reverse cipher.'
translated = '' #cipher text is stored in this variable
i = len(message) - 1

while i >= 0:
   translated = translated + message[i]
   i = i - 1
print(“The cipher text is : “, translated)

出力

あなたは、逆のテキストを見ることができます、それは次の画像に示すように出力です-

出力

説明

  • プレーンテキストは変数メッセージに保存され、翻訳された変数は作成された暗号テキストを保存するために使用されます。
  • プレーンテキストの長さは、 for ループと index number を使用して計算されます。 文字は、最後の行に出力される暗号テキスト変数 translated に保存されます。

Pythonでの暗号化-シーザー暗号

最後の章では、逆暗号を扱いました。 この章では、Caesar暗号について詳しく説明します。

シーザー暗号のアルゴリズム

シーザー暗号のアルゴリズムは、次の機能を保持しています-

  • シーザー暗号技術は、暗号化技術のシンプルで簡単な方法です。
  • これは、単純なタイプの置換暗号です。
  • プレーンテキストの各文字は、アルファベットで固定されたいくつかの位置の文字に置き換えられます。

次の図は、シーザー暗号アルゴリズムの実装の動作を示しています-

シーザー暗号のアルゴリズム

シーザー暗号アルゴリズムのプログラム実装は次のとおりです-

def encrypt(text,s):
result = ""
   # transverse the plain text
   for i in range(len(text)):
      char = text[i]
      # Encrypt uppercase characters in plain text

      if (char.isupper()):
         result += chr((ord(char) + s-65) % 26 + 65)
      # Encrypt lowercase characters in plain text
      else:
         result += chr((ord(char) + s - 97) % 26 + 97)
      return result
#check the above function
text = "CEASER CIPHER DEMO"
s = 4

print "Plain Text : " + text
print "Shift pattern : " + str(s)
print "Cipher: " + encrypt(text,s)

出力

あなたはシーザー暗号を見ることができます、それは次の画像に示すように出力です-

シーザー暗号

説明

プレーンテキスト文字は、一度に1つずつトラバースされます。

  • 指定されたプレーンテキストの各文字について、テキストの暗号化および復号化の手順に応じて、ルールに従って指定された文字を変換します。
  • 手順を実行すると、暗号化テキストと呼ばれる新しい文字列が生成されます。

シーザー暗号アルゴリズムのハッキング

暗号文はさまざまな可能性でハッキングされる可能性があります。 そのような可能性の1つは、 Brute Force Technique です。これには、可能なすべての復号化キーを試すことが含まれます。 この手法はそれほど労力を必要とせず、ハッカーにとって比較的簡単です。

シーザー暗号アルゴリズムをハッキングするためのプログラムの実装は次のとおりです-

message = 'GIEWIVrGMTLIVrHIQS' #encrypted message
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

for key in range(len(LETTERS)):
   translated = ''
   for symbol in message:
      if symbol in LETTERS:
         num = LETTERS.find(symbol)
         num = num - key
         if num < 0:
            num = num + len(LETTERS)
         translated = translated + LETTERS[num]
      else:
         translated = translated + symbol
print('Hacking key #%s: %s' % (key, translated))

前の例で暗号化された暗号文を考えてください。 次に、キーとブルートフォース攻撃技術を使用したハッキン​​グ方法の可能性がある出力は次のとおりです-

シーザー暗号のハッキング

Pythonを使用した暗号化-ROT13アルゴリズム

これまで、逆暗号とシーザー暗号アルゴリズムについて学びました。 次に、ROT13アルゴリズムとその実装について説明します。

ROT13アルゴリズムの説明

ROT13暗号は、省略形* 13桁ずつ回転*を指します。 これは、シフトが常に13であるCaesar Cipherの特殊なケースです。 メッセージを暗号化または復号化するために、すべての文字が13桁シフトされます。

次の図は、ROT13アルゴリズムプロセスを絵で説明しています-

ROT13アルゴリズムプロセス

プログラムコード

ROT13アルゴリズムのプログラム実装は次のとおりです-

from string import maketrans

rot13trans = maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
   'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm')

# Function to translate plain text
def rot13(text):
   return text.translate(rot13trans)
def main():
   txt = "ROT13 Algorithm"
   print rot13(txt)

if __name__ == "__main__":
   main()

次の画像に示すように、ROT13の出力を確認できます-

ROT13

欠点

ROT13アルゴリズムは13シフトを使用します。 したがって、暗号テキストを解読するために文字を逆方向にシフトすることは非常に簡単です。

ROT13アルゴリズムの分析

ROT13暗号アルゴリズムは、Caesar Cipherの特殊なケースと見なされます。 これは非常に安全なアルゴリズムではなく、周波数分析または25の可能なキーを試すだけで簡単に破ることができますが、ROT13は13桁シフトすることで破ることができます。 したがって、実際の使用は含まれません。

転置暗号

転置暗号は、平文のアルファベットの順序が再配置されて暗号文を形成する暗号化アルゴリズムです。 このプロセスでは、実際のプレーンテキストアルファベットは含まれません。

転置暗号の簡単な例は、 columnar transposition cipher です。この場合、プレーンテキストの各文字は、指定されたアルファベット幅で水平に書き込まれます。 暗号は垂直に書き込まれ、まったく異なる暗号テキストが作成されます。

プレーンテキストの hello world を検討し、以下に示すように簡単な円柱転置手法を適用しましょう

円柱転置

プレーンテキスト文字は水平に配置され、暗号テキストは*:holewdlo lr。*のように垂直形式で作成されます。ここで、受信者は同じテーブルを使用して暗号テキストをプレーンテキストに復号化する必要があります。

Code

次のプログラムコードは、円柱転位法の基本的な実装を示しています-

def split_len(seq, length):
   return [seq[i:i + length] for i in range(0, len(seq), length)]
def encode(key, plaintext):
   order = {
      int(val): num for num, val in enumerate(key)
   }
ciphertext = ''

for index in sorted(order.keys()):
   for part in split_len(plaintext, len(key)):
      try:ciphertext += part[order[index]]
         except IndexError:
            continue
   return ciphertext
print(encode('3214', 'HELLO'))

説明

  • 関数* split_len()、*を使用して、列形式または行形式で配置できるプレーンテキスト文字を分割できます。
  • encode メソッドは、列数を指定するキーを使用して暗号化テキストを作成し、各列から文字を読み取って暗号化テキストを印刷するのに役立ちます。

出力

円柱転位法の基本的な実装のためのプログラムコードは、次の出力を与えます-

円柱転置テクニック

-暗号解​​読者は、転置技術を実行すると暗号セキュリティが大幅に向上することを観察しました。 彼らはまた、同じ転置暗号を使用して暗号テキストを再暗号化すると、セキュリティが向上することを指摘しました。

転置暗号の暗号化

前の章で、転置暗号について学びました。 この章では、暗号化について説明します。

パークリップ

Pythonプログラミング言語での pyperclip プラグインの主な用途は、クリップボードにテキストをコピーして貼り付けるためのクロスプラットフォームモジュールを実行することです。 次のコマンドを使用して、python pyperclip モジュールをインストールできます。

pip install pyperclip

要件がシステムに既に存在する場合、次の出力を見ることができます-

Pyperclip

Code

pyperclipがメインモジュールである転置暗号を暗号化するためのPythonコードは以下のとおりです-

import pyperclip
def main():
   myMessage = 'Transposition Cipher'
   myKey = 10
   ciphertext = encryptMessage(myKey, myMessage)

   print("Cipher Text is")
   print(ciphertext + '|')
   pyperclip.copy(ciphertext)

def encryptMessage(key, message):
   ciphertext = [''] * key

   for col in range(key):
      position = col
      while position < len(message):
         ciphertext[col] += message[position]
            position += key
      return ''.join(ciphertext) #Cipher text
if __name__ == '__main__':
   main()

出力

*pyperclip* がメインモジュールである転置暗号を暗号化するためのプログラムコードは、次の出力を与えます-

暗号化転置

説明

  • 関数* main() encryptMessage()を呼び出します。これには、 *len 関数を使用して文字を分割し、列形式でそれらを反復する手順が含まれます。
  • メイン関数は、適切な出力を取得するために最後に初期化されます。

転置暗号の復号化

この章では、転置暗号を復号化する手順を学習します。

Code

転置暗号の解読についての理解を深めるために、次のコードを観察してください。 6 のキーを持つメッセージ Transposition Cipher の暗号テキストは、* Toners raiCntisippoh。*としてフェッチされます。

import math, pyperclip
def main():
   myMessage= 'Toners raiCntisippoh'
   myKey = 6
   plaintext = decryptMessage(myKey, myMessage)

   print("The plain text is")
   print('Transposition Cipher')

def decryptMessage(key, message):
   numOfColumns = math.ceil(len(message)/key)
   numOfRows = key
   numOfShadedBoxes = (numOfColumns *numOfRows) - len(message)
   plaintext = float('')* numOfColumns
   col = 0
   row = 0

   for symbol in message:
      plaintext[col] += symbol
      col += 1
      if (col == numOfColumns) or (col == numOfColumns - 1 and row >= numOfRows - numOfShadedBoxes):
         col = 0 row += 1 return ''.join(plaintext)
if __name__ == '__main__':
   main()

説明

暗号化テキストと前述のキーは、文字を列形式で配置し、水平方向に読み取ることにより、暗号化テキストを逆手法で復号化または復号化するための入力パラメーターとして取得される2つの値です。

あなたは列形式で文字を配置し、後で結合するか、次のコードを使用してそれらを一緒に連結することができます-

for symbol in message:
   plaintext[col] += symbol
   col += 1

   if (col == numOfColumns) or (col == numOfColumns - 1 and row >= numOfRows - numOfShadedBoxes):
   col = 0
   row += 1
return ''.join(plaintext)

出力

転置暗号を解読するためのプログラムコードは、次の出力を与えます-

トランスポーズの解読

ファイルの暗号化

Pythonでは、通信チャネルに送信する前にファイルを暗号化および復号化できます。 このためには、プラグイン PyCrypto を使用する必要があります。 以下のコマンドを使用して、このプラグインをインストールできます。

pip install pycrypto

PyCrypto

Code

パスワードプロテクターでファイルを暗号化するためのプログラムコードは以下に記載されています-

# =================Other Configuration================
# Usages :
usage = "usage: %prog [options] "
# Version
Version="%prog 0.0.1"
# ====================================================
# Import Modules
import optparse, sys,os
from toolkit import processor as ps
def main():
   parser = optparse.OptionParser(usage = usage,version = Version)
   parser.add_option(
      '-i','--input',type = 'string',dest = 'inputfile',
      help = "File Input Path For Encryption", default = None)

   parser.add_option(
      '-o','--output',type = "string",dest = 'outputfile',
      help = "File Output Path For Saving Encrypter Cipher",default = ".")

   parser.add_option(
      '-p','--password',type = "string",dest = 'password',
      help = "Provide Password For Encrypting File",default = None)

   parser.add_option(
      '-p','--password',type = "string",dest = 'password',
      help = "Provide Password For Encrypting File",default = None)

   (options, args)= parser.parse_args()

   # Input Conditions Checkings
   if not options.inputfile or not os.path.isfile(options.inputfile):
      print " [Error] Please Specify Input File Path"
      exit(0)
   if not options.outputfile or not os.path.isdir(options.outputfile):
      print " [Error] Please Specify Output Path"
      exit(0)
   if not options.password:
      print " [Error] No Password Input"
      exit(0)
   inputfile = options.inputfile

   outputfile = os.path.join(
      options.outputfile,os.path.basename(options.inputfile).split('.')[0]+'.ssb')
   password = options.password
   base = os.path.basename(inputfile).split('.')[1]
   work = "E"

   ps.FileCipher(inputfile,outputfile,password,work)
   return

   if __name__ == '__main__':
   main()

次のコマンドを使用して、パスワードとともに暗号化プロセスを実行できます-

python pyfilecipher-encrypt.py -i file_path_for_encryption -o output_path -p password

出力

上記のコードを実行すると、次の出力を確認できます-

暗号化プロセス

説明

パスワードはMD5ハッシュアルゴリズムを使用して生成され、値はWindowsシステムの単純に安全なバックアップファイルに保存されます。これには以下に表示される値が含まれます-

説明

ファイルの復号化

この章では、Pythonを使用した暗号化でのファイルの復号化について説明します。 復号化プロセスについても同じ手順に従いますが、出力パスを指定する代わりに、入力パスまたは暗号化された必要なファイルに焦点を合わせることに注意してください。

Code

以下は、Pythonを使用して暗号化でファイルを復号化するためのサンプルコードです-

#!/usr/bin/python
# ---------------- READ ME ---------------------------------------------
# This Script is Created Only For Practise And Educational Purpose Only
# This Script Is Created For http://bitforestinfo.blogspot.in
# This Script is Written By
#
#
##################################################
######## Please Don't Remove Author Name #########
############### Thanks ###########################
##################################################
#
#
# =================Other Configuration================
# Usages :
usage = "usage: %prog [options] "
# Version
Version="%prog 0.0.1"
# ====================================================
# Import Modules
import optparse, sys,os
from toolkit import processor as ps
def main():
   parser = optparse.OptionParser(usage = usage,version = Version)
   parser.add_option(
      '-i','--input',type = 'string',dest = 'inputfile',
      help = "File Input Path For Encryption", default = None)

   parser.add_option(
      '-o','--output',type = "string",dest = 'outputfile',
      help = "File Output Path For Saving Encrypter Cipher",default = ".")

   parser.add_option(
      '-p','--password',type = "string",dest = 'password',
      help = "Provide Password For Encrypting File",default = None)
      (options, args) =  parser.parse_args()
      # Input Conditions Checkings
      if not options.inputfile or not os.path.isfile(options.inputfile):
         print " [Error] Please Specify Input File Path"
         exit(0)
      if not options.outputfile or not os.path.isdir(options.outputfile):
         print " [Error] Please Specify Output Path"
         exit(0)
      if not options.password:
         print " [Error] No
         exit(0)
      inputfile = options.inputfile
      outputfile = options.outputfile
      password = options.password
      work = "D"
      ps.FileCipher(inputfile,outputfile,password,work)
      return
if __name__ == '__main__':
   main()

上記のコードを実行するには、次のコマンドを使用できます-

python pyfilecipher-decrypt.py -i encrypted_file_path -p password

出力

上記のコマンドを実行すると、次のコードを観察できます-

復号化

-出力は、暗号化前および復号化後のハッシュ値を指定します。これにより、同じファイルが暗号化され、プロセスが成功したことを記録します。

Base64エンコードおよびデコード

Base64エンコードは、バイナリデータをテキスト形式に変換します。これは、ユーザーがテキストを安全に処理できる通信チャネルを介して渡されます。 Base64は* Privacy Enhanced Electronic Mail(PEM)*とも呼ばれ、主に電子メールの暗号化プロセスで使用されます。

Pythonには、 BASE64 というモジュールが含まれています。このモジュールには、次の2つの主要な機能が含まれています-

  • * base64.decode(input、output)*-指定された入力値パラメーターをデコードし、デコードされた出力をオブジェクトとして保存します。
  • * Base64.encode(input、output)*-指定された入力値パラメーターをエンコードし、デコードされた出力をオブジェクトとして保存します。

エンコード用プログラム

次のコードを使用して、base64エンコードを実行できます-

import base64
encoded_data = base64.b64encode("Encode this text")

print("Encoded text with base 64 is")
print(encoded_data)

出力

base64エンコーディングのコードは次の出力を提供します-

Base64

デコード用プログラム

次のコードを使用して、base64デコードを実行できます-

import base64
decoded_data = base64.b64decode("RW5jb2RlIHRoaXMgdGV4dA==")

print("decoded text is ")
print(decoded_data)

出力

base64デコード用のコードはあなたに次の出力を提供します-

Base64 Decoding

ASCIIとbase64の違い

あなたはデータをエンコードするためにASCIIとbase64で作業するときに次の違いを観察することができます-

  • テキストをASCIIでエンコードする場合、テキスト文字列から始めて、それを一連のバイトに変換します。
  • Base64でデータをエンコードする場合、一連のバイトから始めてテキスト文字列に変換します。

欠点

Base64アルゴリズムは通常、データベースにパスワードを保存するために使用されます。 主な欠点は、デコードされた各単語をオンラインツールで簡単にエンコードでき、侵入者が情報を簡単に取得できることです。

Pythonでの暗号化-XORプロセス

この章では、XORプロセスとPythonでのコーディングについて説明します。

アルゴリズム

暗号化および復号化のXORアルゴリズムは、ASCIIバイト形式のプレーンテキストを変換し、XORプロシージャを使用して指定されたバイトに変換します。 それはそのユーザーに次の利点を提供します-

  • 高速計算
  • 左右に違いはありません
  • わかりやすく分析しやすい

Code

次のコードを使用して、XORプロセスを実行できます-

def xor_crypt_string(data, key = 'awesomepassword', encode = False, decode = False):
   from itertools import izip, cycle
   import base64

   if decode:
      data = base64.decodestring(data)
   xored = ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(data, cycle(key)))

   if encode:
      return base64.encodestring(xored).strip()
   return xored
secret_data = "XOR procedure"

print("The cipher text is")
print xor_crypt_string(secret_data, encode = True)
print("The plain text fetched")
print xor_crypt_string(xor_crypt_string(secret_data, encode = True), decode = True)

出力

XORプロセスのコードはあなたに次の出力を提供します-

xor

説明

  • 関数* xor_crypt_string()*には、エンコードおよびデコードのモードと文字列値を指定するパラメーターが含まれています。
  • 基本機能はbase64モジュールで使用され、XOR手順/操作に従ってプレーンテキスト/暗号化テキストを暗号化または復号化します。

-XOR暗号化はデータの暗号化に使用され、ブルートフォース方式、つまり正しい暗号化テキストと一致するランダムな暗号化キーを生成することによって解読するのは困難です。

乗法暗号

Caesar暗号技術を使用している間、シンボルの暗号化と復号化には、単純な基本的な加算または減算の手順で値を数値に変換することが含まれます。

乗算を使用して暗号テキストに変換する場合、「ラップアラウンド」状況と呼ばれます。 以下に示すように使用される文字と関連する数字を考慮してください-

関連付けられた番号

数値は乗算手順に使用され、関連するキーは7です。 乗法暗号を生成するためにそのようなシナリオで使用される基本的な式は次のとおりです-

(Alphabet Number *key)mod(total number of alphabets)

出力を介してフェッチされた番号は、上記の表にマッピングされ、対応する文字が暗号化された文字と見なされます。

暗号化されたレター

Pythonの乗法暗号の基本的な変調関数は次のとおりです-

def unshift(key, ch):
   offset = ord(ch) - ASC_A
   return chr(((key[0]* (offset + key[1])) % WIDTH) + ASC_A)

-乗法暗号の利点は、8,953,851のような非常に大きなキーで動作できることです。 コンピューターが900万個のキーの大部分をブルートフォースするのに非常に長い時間がかかります。

Pythonを使用した暗号化-アフィン暗号

アフィン暗号は、乗法暗号とシーザー暗号アルゴリズムの組み合わせです。 アフィン暗号の基本的な実装は、以下の画像に示すとおりです-

アフィン暗号の基本的な実装

この章では、暗号化と復号化の2つの基本機能を含む対応するクラスを作成することにより、アフィン暗号を実装します。

Code

次のコードを使用して、アフィン暗号を実装できます-

class Affine(object):
   DIE = 128
   KEY = (7, 3, 55)
   def __init__(self):
      pass
   def encryptChar(self, char):
      K1, K2, kI = self.KEY
      return chr((K1 *ord(char) + K2) % self.DIE)

   def encrypt(self, string):
      return "".join(map(self.encryptChar, string))

   def decryptChar(self, char):
      K1, K2, KI = self.KEY
      return chr(KI* (ord(char) - K2) % self.DIE)

   def decrypt(self, string):
      return "".join(map(self.decryptChar, string))
        affine = Affine()
print affine.encrypt('Affine Cipher')
print affine.decrypt('*18?FMT')

出力

アフィン暗号を実装すると、次の出力を観察できます-

アフィン

出力には、プレーンテキストメッセージ Affine Cipher の暗号化されたメッセージと、入力* abcdefg。*として送信されたメッセージの復号化されたメッセージが表示されます。

モノアルファベット暗号のハッキング

この章では、単一アルファベット暗号とPythonを使用したそのハッキングについて学習します。

単一アルファベット暗号

Monoalphabetic暗号は、メッセージ全体を暗号化するために固定置換を使用します。 JSONオブジェクトを含むPython辞書を使用したモノアルファベット暗号がここに示されています-

monoalpha_cipher = {
   'a': 'm',
   'b': 'n',
   'c': 'b',
   'd': 'v',
   'e': 'c',
   'f': 'x',
   'g': 'z',
   'h': 'a',
   'i': 's',
   'j': 'd',
   'k': 'f',
   'l': 'g',
   'm': 'h',
   'n': 'j',
   'o': 'k',
   'p': 'l',
   'q': 'p',
   'r': 'o',
   's': 'i',
   't': 'u',
   'u': 'y',
   'v': 't',
   'w': 'r',
   'x': 'e',
   'y': 'w',
   'z': 'q',
    ' ': ' ',
}

この辞書の助けを借りて、JSONオブジェクトの値として、関連付けられた文字で文字を暗号化できます。 次のプログラムは、暗号化と復号化のすべての機能を含むクラス表現として、アルファベット順のプログラムを作成します。

from string import letters, digits
from random import shuffle

def random_monoalpha_cipher(pool = None):
   if pool is None:
      pool = letters + digits
   original_pool = list(pool)
   shuffled_pool = list(pool)
   shuffle(shuffled_pool)
   return dict(zip(original_pool, shuffled_pool))

def inverse_monoalpha_cipher(monoalpha_cipher):
   inverse_monoalpha = {}
   for key, value in monoalpha_cipher.iteritems():
      inverse_monoalpha[value] = key
   return inverse_monoalpha

def encrypt_with_monoalpha(message, monoalpha_cipher):
   encrypted_message = []
   for letter in message:
      encrypted_message.append(monoalpha_cipher.get(letter, letter))
   return ''.join(encrypted_message)

def decrypt_with_monoalpha(encrypted_message, monoalpha_cipher):
   return encrypt_with_monoalpha(
      encrypted_message,
      inverse_monoalpha_cipher(monoalpha_cipher)
   )

このファイルは、後述するMonoalphabetic暗号の暗号化および復号化プロセスを実装するために後で呼び出されます-

import monoalphabeticCipher as mc

cipher = mc.random_monoalpha_cipher()
print(cipher)
encrypted = mc.encrypt_with_monoalpha('Hello all you hackers out there!', cipher)
decrypted = mc.decrypt_with_monoalpha('sXGGt SGG Nt0 HSrLXFC t0U UHXFX!', cipher)

print(encrypted)
print(decrypted)

出力

上記のコードを実装すると、次の出力を確認できます-

モノアルファベット

したがって、指定されたキーと値のペアを持つモノアルファベット暗号をハッキングして、暗号テキストを実際のプレーンテキストに分解できます。

単純な置換暗号

単純置換暗号は、最も一般的に使用される暗号であり、すべての暗号テキスト文字をすべてのプレーンテキスト文字に置き換えるアルゴリズムが含まれています。 このプロセスでは、Caesar暗号アルゴリズムと比較してアルファベットが乱雑になります。

単純な置換暗号のキーは、通常26文字で構成されます。 例のキーは-

plain alphabet : abcdefghijklmnopqrstuvwxyz
cipher alphabet: phqgiumeaylnofdxjkrcvstzwb

上記のキーを使用した暗号化の例は次のとおりです-

plaintext : defend the east wall of the castle
ciphertext: giuifg cei iprc tpnn du cei qprcni

次のコードは、単純な置換暗号を実装するプログラムを示しています-

import random, sys

LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
def main():
   message = ''
   if len(sys.argv) > 1:
      with open(sys.argv[1], 'r') as f:
         message = f.read()
   else:
      message = raw_input("Enter your message: ")
   mode = raw_input("E for Encrypt, D for Decrypt: ")
   key = ''

   while checkKey(key) is False:
      key = raw_input("Enter 26 ALPHA key (leave blank for random key): ")
      if key == '':
         key = getRandomKey()
      if checkKey(key) is False:
        print('There is an error in the key or symbol set.')
   translated = translateMessage(message, key, mode)
   print('Using key: %s' % (key))

   if len(sys.argv) > 1:
      fileOut = 'enc.' + sys.argv[1]
      with open(fileOut, 'w') as f:
         f.write(translated)
      print('Success! File written to: %s' % (fileOut))
   else: print('Result: ' + translated)

# Store the key into list, sort it, convert back, compare to alphabet.
def checkKey(key):
   keyString = ''.join(sorted(list(key)))
   return keyString == LETTERS
def translateMessage(message, key, mode):
   translated = ''
   charsA = LETTERS
   charsB = key

   # If decrypt mode is detected, swap A and B
   if mode == 'D':
      charsA, charsB = charsB, charsA
   for symbol in message:
      if symbol.upper() in charsA:
         symIndex = charsA.find(symbol.upper())
         if symbol.isupper():
            translated += charsB[symIndex].upper()
         else:
            translated += charsB[symIndex].lower()
                else:
               translated += symbol
         return translated
def getRandomKey():
   randomList = list(LETTERS)
   random.shuffle(randomList)
   return ''.join(randomList)
if __name__ == '__main__':
   main()

出力

上記のコードを実装すると、次の出力を確認できます-

単純な置換

単純な置換暗号のテスト

この章では、以下に示すようにランダム文字列を生成するのに役立つさまざまな方法を使用して置換暗号をテストすることに焦点を当てます-

import random, string, substitution
def main():
   for i in range(1000):
      key = substitution.getRandomKey()
      message = random_string()
      print('Test %s: String: "%s.."' % (i + 1, message[:50]))
      print("Key: " + key)
      encrypted = substitution.translateMessage(message, key, 'E')
      decrypted = substitution.translateMessage(encrypted, key, 'D')

      if decrypted != message:
         print('ERROR: Decrypted: "%s" Key: %s' % (decrypted, key))
         sys.exit()
      print('Substutition test passed!')

def random_string(size = 5000, chars = string.ascii_letters + string.digits):
   return ''.join(random.choice(chars) for _ in range(size))
if __name__ == '__main__':
   main()

出力

以下に示すように、ランダムなプレーンテキストメッセージの生成に役立つランダムに生成された文字列として出力を観察できます-

文字列

テストが正常に完了すると、出力メッセージ Substitution test pass !! を確認できます。

置換

したがって、体系的な方法で置換暗号をハッキングできます。

単純な置換暗号の復号化

この章では、単純な置換暗号技術で使用されるロジックに従って暗号化および復号化されたメッセージを表示する置換暗号の簡単な実装について学習できます。 これは、コーディングの代替アプローチと見なすことができます。

Code

次のコードを使用して、単純な置換暗号を使用して復号化を実行できます-

import random
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + \
   'abcdefghijklmnopqrstuvwxyz' + \
   '0123456789' + \
   ':.;,?!@#$%&()+=-*/_<> []{}`~^"\'\\'

def generate_key():
   """Generate an key for our cipher"""
   shuffled = sorted(chars, key=lambda k: random.random())
   return dict(zip(chars, shuffled))

def encrypt(key, plaintext):
   """Encrypt the string and return the ciphertext"""
   return ''.join(key[l] for l in plaintext)

def decrypt(key, ciphertext):
   """Decrypt the string and return the plaintext"""
   flipped = {v: k for k, v in key.items()}
   return ''.join(flipped[l] for l in ciphertext)

def show_result(plaintext):
   """Generate a resulting cipher with elements shown"""
   key = generate_key()
   encrypted = encrypt(key, plaintext)
   decrypted = decrypt(key, encrypted)

   print 'Key: %s' % key
    print 'Plaintext: %s' % plaintext
   print 'Encrypted: %s' % encrypted
   print 'Decrypted: %s' % decrypted
show_result('Hello World. This is demo of substitution cipher')

出力

上記のコードは、ここに示すように出力を提供します-

実装

暗号化のPythonモジュール

この章では、Pythonの暗号化のさまざまなモジュールについて詳しく学習します。

暗号化モジュール

すべてのレシピとプリミティブが含まれており、Pythonでのコーディングの高レベルインターフェイスを提供します。 次のコマンドを使用して暗号化モジュールをインストールできます-

pip install cryptography

PIPインストール

Code

次のコードを使用して暗号化モジュールを実装できます-

from cryptography.fernet import Fernet
key = Fernet.generate_key()
cipher_suite = Fernet(key)
cipher_text = cipher_suite.encrypt("This example is used to demonstrate cryptography module")
plain_text = cipher_suite.decrypt(cipher_text)

出力

上記のコードは、次の出力を生成します-

認証

ここで指定されたコードは、パスワードを検証し、そのハッシュを作成するために使用されます。 また、認証目的でパスワードを検証するためのロジックも含まれています。

import uuid
import hashlib

def hash_password(password):
   # uuid is used to generate a random number of the specified password
   salt = uuid.uuid4().hex
   return hashlib.sha256(salt.encode() + password.encode()).hexdigest() + ':' + salt

def check_password(hashed_password, user_password):
   password, salt = hashed_password.split(':')
   return password == hashlib.sha256(salt.encode() + user_password.encode()).hexdigest()

new_pass = input('Please enter a password: ')
hashed_password = hash_password(new_pass)
print('The string to store in the db is: ' + hashed_password)
old_pass = input('Now please enter the password again to check: ')

if check_password(hashed_password, old_pass):
   print('You entered the right password')
else:
   print('Passwords do not match')

出力

  • シナリオ1 *-正しいパスワードを入力した場合、次の出力を見つけることができます-

正しいパスワード

  • シナリオ2 *-間違ったパスワードを入力した場合、次の出力を見つけることができます-

間違ったパスワード

説明

*Hashlib* パッケージは、データベースにパスワードを保存するために使用されます。 このプログラムでは、ハッシュ関数を実装する前にパスワード文字列にランダムシーケンスを追加する *salt* が使用されます。

Vignere暗号について

Vignere Cipherには、暗号化と復号化に使用されるCaesar Cipherアルゴリズムを使用したツイストが含まれています。 Vignere CipherはCaesar Cipherアルゴリズムと同様に機能しますが、主要な違いは1つだけです。CaesarCipherには1文字シフトのアルゴリズムが含まれていますが、Vignere Cipherには複数のアルファベットシフトのキーが含まれています。

数学方程式

暗号化のための数学的な方程式は次のとおりです-

E _ \ {k} \ left(M \ {_ \ {i \ {}}} \ right)= \ left(M _ \ {i} + K _ \ {i} \ right)\; \; \; mod \; \; 26

解読のための数学的な方程式は次のとおりです-

D _ \ {k} \ left(C \ {_ \ {i \ {}}} \ right)= \ left(C _ \ {i} -K _ \ {i} \ right)\; \; \; mod \; \; 26

Vignere暗号は複数の置換セットを使用するため、 polyalphabetic cipher とも呼ばれます。 Vignere Cipherは、数値キー表現ではなく文字キーを使用します。キー0には文字A、キー1には文字Bなどが使用されます。 暗号化プロセスの前後の文字の数は以下に示されています-

polyalphabetic cipher

Vignereキーの長さに基づいて可能なキーの数の可能な組み合わせは次のように与えられ、それはVignere暗号アルゴリズムがどれだけ安全であるかの結果を与えます

Vignere Cipher

ヴィニエールタブロー

Vignere暗号に使用されるタブローは以下のとおりです-

Vignere Tableau

Vignere Cipherの実装

この章では、Vignere暗号を実装する方法を理解しましょう。 テキストを考慮してください*これはVignere Cipher の基本実装であり、エンコードされるキーは PIZZAです*。

Code

次のコードを使用して、PythonでVignere暗号を実装できます-

import pyperclip

LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
def main():
   myMessage = "This is basic implementation of Vignere Cipher"
   myKey = 'PIZZA'
   myMode = 'encrypt'

   if myMode == 'encrypt':
      translated = encryptMessage(myKey, myMessage)
   elif myMode == 'decrypt':
      translated = decryptMessage(myKey, myMessage)

   print('%sed message:' % (myMode.title()))
   print(translated)
   print()
def encryptMessage(key, message):
   return translateMessage(key, message, 'encrypt')
def decryptMessage(key, message):
   return translateMessage(key, message, 'decrypt')
def translateMessage(key, message, mode):
   translated = [] # stores the encrypted/decrypted message string
   keyIndex = 0
   key = key.upper()

   for symbol in message:
      num = LETTERS.find(symbol.upper())
      if num != -1:
         if mode == 'encrypt':
            num += LETTERS.find(key[keyIndex])
                elif mode == 'decrypt':
               num -= LETTERS.find(key[keyIndex])
            num %= len(LETTERS)

            if symbol.isupper():
               translated.append(LETTERS[num])
            elif symbol.islower():
               translated.append(LETTERS[num].lower())
            keyIndex += 1

            if keyIndex == len(key):
               keyIndex = 0
         else:
            translated.append(symbol)
      return ''.join(translated)
if __name__ == '__main__':
   main()

出力

上記のコードを実装すると、次の出力を確認できます-

セキュア暗号化モード

Vignere暗号のハッキングの可能な組み合わせはほとんど不可能です。 したがって、これは安全な暗号化モードと見なされます。

ワンタイムパッド暗号

ワンタイムパッド暗号は、次の機能を含むVignere暗号の一種です-

  • これは壊れない暗号です。
  • キーは、暗号化されるメッセージの長さとまったく同じです。
  • キーはランダムなシンボルで構成されています。
  • 名前が示すように、キーは1回だけ使用され、暗号化される他のメッセージに再び使用されることはありません。

このため、暗号化されたメッセージは、暗号解読者に対する攻撃に対して脆弱になります。 ワンタイムパッド暗号に使用されるキーは、 pad と呼ばれ、紙のパッドに印刷されます。

なぜ壊れないのですか?

キーは、次の機能のために壊れないです-

  • キーは、指定されたメッセージと同じ長さです。
  • キーは本当にランダムで、特別に自動生成されます。
  • モジュロ10/26/2として計算されたキーおよびプレーンテキスト。
  • 各キーは1回使用し、送信者と受信者の両方で破棄する必要があります。
  • キーのコピーが2つあるはずです。1つは送信者に、もう1つは受信者にあります。

暗号化

手紙を暗号化するには、ユーザーは平文の下に鍵を書く必要があります。 平文の文字が上部に、キーの文字が左側に配置されます。 2つの文字間で達成される断面はプレーンテキストです。 以下の例で説明されています-

OTP

復号化

レターを解読するには、ユーザーは左側のキーレターを取得し、その行で暗号テキストレターを見つけます。 プレーンテキストの文字は、ユーザーが暗号テキストの文字を見つけることができる列の上部に配置されます。

ワンタイムパッド暗号の実装

Pythonには、*ワンタイムパッド*暗号実装のためのハッキング実装モジュールが含まれています。 パッケージ名はワンタイムパッドと呼ばれ、ワンタイムパッド暗号アルゴリズムと同様の暗号化メカニズムを使用するコマンドライン暗号化ツールが含まれています。

インストール

次のコマンドを使用して、このモジュールをインストールできます-

pip install onetimepad

あなたがコマンドラインからそれを使用したい場合は、次のコマンドを実行します-

onetimepad

PIP

Code

次のコードは、ワンタイムパッド暗号を生成するのに役立ちます-

import onetimepad

cipher = onetimepad.encrypt('One Time Cipher', 'random')
print("Cipher text is ")
print(cipher)
print("Plain text is ")
msg = onetimepad.decrypt(cipher, 'random')

print(msg)

出力

上記のコードを実行すると、次の出力を確認できます-

PIP出力

-キーの長さがメッセージの長さ(プレーンテキスト)より短い場合、暗号化されたメッセージは非常に簡単に解読されます。

いずれにせよ、キーは必ずしもランダムではないため、ワンタイムパッド暗号は価値のあるツールとなります。

対称および非対称暗号化

この章では、対称暗号化と非対称暗号化について詳しく説明します。

対称暗号化

このタイプでは、暗号化および復号化プロセスは同じキーを使用します。 *秘密鍵暗号*とも呼ばれます。 対称暗号の主な特徴は次のとおりです-

  • よりシンプルで高速です。
  • 両者は安全な方法で鍵を交換します。

欠点

対称暗号化の主な欠点は、キーが侵入者に漏洩した場合、メッセージが簡単に変更される可能性があり、これがリスク要因と見なされることです。

データ暗号化標準(DES)

最も一般的な対称鍵アルゴリズムはデータ暗号化標準(DES)であり、PythonにはDESアルゴリズムの背後にあるロジックを含むパッケージが含まれています。

インストール

PythonでDESパッケージ pyDES をインストールするためのコマンドは-

pip install pyDES

pyDES

DESアルゴリズムの簡単なプログラム実装は次のとおりです-

import pyDes

data = "DES Algorithm Implementation"
k = pyDes.des("DESCRYPT", pyDes.CBC, "\0\0\0\0\0\0\0\0", pad=None, padmode=pyDes.PAD_PKCS5)
d = k.encrypt(data)

print "Encrypted: %r" % d
print "Decrypted: %r" % k.decrypt(d)
assert k.decrypt(d) == data

DESアルゴリズムの実装ごとにすべてのパッケージを取得し、指定された方法で暗号化と復号化を行う変数 padmode を呼び出します。

出力

あなたは上記のコードの結果として次の出力を見ることができます-

DESアルゴリズム

非対称暗号化

  • 公開鍵暗号方式とも呼ばれます。対称暗号方式の逆の方法で機能します。 これは、暗号化用と復号化用の2つのキーが必要であることを意味します。 公開鍵は暗号化に使用され、秘密鍵は復号化に使用されます。

欠点

  • キーの長さにより、暗号化速度が低下します。
  • キー管理は非常に重要です。

Pythonの次のプログラムコードは、RSAアルゴリズムとその実装を使用した非対称暗号化の動作を示しています-

from Crypto import Random
from Crypto.PublicKey import RSA
import base64

def generate_keys():
   # key length must be a multiple of 256 and >= 1024
   modulus_length = 256*4
   privatekey = RSA.generate(modulus_length, Random.new().read)
   publickey = privatekey.publickey()
   return privatekey, publickey

def encrypt_message(a_message , publickey):
   encrypted_msg = publickey.encrypt(a_message, 32)[0]
   encoded_encrypted_msg = base64.b64encode(encrypted_msg)
   return encoded_encrypted_msg

def decrypt_message(encoded_encrypted_msg, privatekey):
   decoded_encrypted_msg = base64.b64decode(encoded_encrypted_msg)
   decoded_decrypted_msg = privatekey.decrypt(decoded_encrypted_msg)
   return decoded_decrypted_msg

a_message = "This is the illustration of RSA algorithm of asymmetric cryptography"
privatekey , publickey = generate_keys()
encrypted_msg = encrypt_message(a_message , publickey)
decrypted_msg = decrypt_message(encrypted_msg, privatekey)

print "%s - (%d)" % (privatekey.exportKey() , len(privatekey.exportKey()))
print "%s - (%d)" % (publickey.exportKey() , len(publickey.exportKey()))
print " Original content: %s - (%d)" % (a_message, len(a_message))
print "Encrypted message: %s - (%d)" % (encrypted_msg, len(encrypted_msg))
print "Decrypted message: %s - (%d)" % (decrypted_msg, len(decrypted_msg))

出力

上記のコードを実行すると、次の出力を見つけることができます-

RSA

RSAアルゴリズムについて

RSAアルゴリズムは公開キー暗号化技術であり、暗号化の最も安全な方法と見なされています。 1978年にRivest、Shamir、およびAdlemanによって発明されたため、 RSA アルゴリズムと名付けられました。

アルゴリズム

RSAアルゴリズムは、次の機能を保持しています-

  • RSAアルゴリズムは、素数を含む整数上の有限体で一般的な累乗法です。
  • この方法で使用される整数は十分に大きいため、解決が困難です。
  • このアルゴリズムには、秘密キーと公開キーの2つのキーセットがあります。

あなたは、RSAアルゴリズムに取り組むために次の手順を経る必要があります-

ステップ1:RSAモジュラスを生成する

最初の手順は、2つの素数、つまりpとqの選択から始まり、次に示すように、それらの積Nを計算します-

N=p*q

ここで、Nを指定された大きな数にします。

ステップ2:派生番号(e)

数eは、1より大きく、(p-1)および(q-1)未満である必要がある派生数として考えてください。 主な条件は、1を除いて(p-1)と(q-1)の共通因子がないことです。

ステップ3:公開鍵

指定された数字のペア ne がRSA公開鍵を形成し、公開されます。

ステップ4:秘密鍵

秘密鍵 d は、数値p、q、およびeから計算されます。 数字間の数学的な関係は次のとおりです-

ed = 1 mod (p-1) (q-1)

上記の式は、拡張ユークリッドアルゴリズムの基本式であり、入力パラメーターとしてpとqを取ります。

暗号化の式

公開キーが*(n、e)*である人にプレーンテキストメッセージを送信する送信者を考えます。特定のシナリオでプレーンテキストメッセージを暗号化するには、次の構文を使用します-

C = Pe mod n

復号式

復号化プロセスは非常に簡単で、体系的なアプローチで計算するための分析が含まれます。 受信者 C が秘密鍵 d を持っていることを考慮すると、結果のモジュラスは次のように計算されます-

Plaintext = Cd mod n

RSAキーの作成

この章では、Pythonを使用したRSAアルゴリズムの段階的な実装に焦点を当てます。

RSAキーの生成

次の手順は、RSAキーの生成に関係します-

  • 2つの大きな素数、つまり pq を作成します。 これらの数値の積は n と呼ばれます。 n = p q *
  • (p-1)*および(q-1)。と比較的素数の乱数を生成します。*を *e として呼び出します。
  • eのモジュラー逆関数を計算します。 計算された逆関数は d として呼び出されます。

RSAキーを生成するためのアルゴリズム

Pythonを使用してRSAキーを生成するには、* Cryptomathモジュール*と* Rabin Millerモジュール*の2つの主要なアルゴリズムが必要です。

暗号化モジュール

RSAアルゴリズムのすべての基本的な実装に従うcryptomathモジュールのソースコードは次のとおりです-

def gcd(a, b):
   while a != 0:
      a, b = b % a, a
   return b

def findModInverse(a, m):
   if gcd(a, m) != 1:
      return None
   u1, u2, u3 = 1, 0, a
   v1, v2, v3 = 0, 1, m

   while v3 != 0:
      q = u3//v3
         v1, v2, v3, u1, u2, u3 = (u1 - q *v1), (u2 - q* v2), (u3 - q *v3), v1, v2, v3
   return u1 % m

RabinMillerモジュール

RSAアルゴリズムのすべての基本的な実装に従うRabinMillerモジュールのソースコードは次のとおりです-

import random
def rabinMiller(num):
   s = num - 1
   t = 0

   while s % 2 == 0:
      s = s//2
      t += 1
   for trials in range(5):
      a = random.randrange(2, num - 1)
      v = pow(a, s, num)
      if v != 1:
         i = 0
         while v != (num - 1):
            if i == t - 1:
               return False
            else:
               i = i + 1
               v = (v* * 2) % num
      return True
def isPrime(num):
   if (num 7< 2):
      return False
   lowPrimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
   67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
   157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241,
   251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313,317, 331, 337, 347, 349,
   353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449,
   457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569,
   571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661,
   673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787,
   797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907,
   911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]

   if num in lowPrimes:
      return True
   for prime in lowPrimes:
      if (num % prime == 0):
         return False
   return rabinMiller(num)
def generateLargePrime(keysize = 1024):
   while True:
      num = random.randrange(2**(keysize-1), 2**(keysize))
      if isPrime(num):
         return num

RSAキーを生成するための完全なコードは次のとおりです-

import random, sys, os, rabinMiller, cryptomath

def main():
   makeKeyFiles('RSA_demo', 1024)

def generateKey(keySize):
   # Step 1: Create two prime numbers, p and q. Calculate n = p *q.
   print('Generating p prime...')
   p = rabinMiller.generateLargePrime(keySize)
   print('Generating q prime...')
   q = rabinMiller.generateLargePrime(keySize)
   n = p* q

   # Step 2: Create a number e that is relatively prime to (p-1)*(q-1).
   print('Generating e that is relatively prime to (p-1)*(q-1)...')
   while True:
      e = random.randrange(2 * *(keySize - 1), 2*  *(keySize))
      if cryptomath.gcd(e, (p - 1)* (q - 1)) == 1:
         break

   # Step 3: Calculate d, the mod inverse of e.
   print('Calculating d that is mod inverse of e...')
   d = cryptomath.findModInverse(e, (p - 1) * (q - 1))
   publicKey = (n, e)
   privateKey = (n, d)
   print('Public key:', publicKey)
   print('Private key:', privateKey)
   return (publicKey, privateKey)

def makeKeyFiles(name, keySize):
   # Creates two files 'x_pubkey.txt' and 'x_privkey.txt'
      (where x is the value in name) with the the n,e and d,e integers written in them,
   # delimited by a comma.
   if os.path.exists('%s_pubkey.txt' % (name)) or os.path.exists('%s_privkey.txt' % (name)):
      sys.exit('WARNING: The file %s_pubkey.txt or %s_privkey.txt already exists! Use a different name or delete these files and re-run this program.' % (name, name))
   publicKey, privateKey = generateKey(keySize)
   print()
   print('The public key is a %s and a %s digit number.' % (len(str(publicKey[0])), len(str(publicKey[1]))))
   print('Writing public key to file %s_pubkey.txt...' % (name))

   fo = open('%s_pubkey.txt' % (name), 'w')
    fo.write('%s,%s,%s' % (keySize, publicKey[0], publicKey[1]))
   fo.close()
   print()
   print('The private key is a %s and a %s digit number.' % (len(str(publicKey[0])), len(str(publicKey[1]))))
   print('Writing private key to file %s_privkey.txt...' % (name))

   fo = open('%s_privkey.txt' % (name), 'w')
   fo.write('%s,%s,%s' % (keySize, privateKey[0], privateKey[1]))
   fo.close()
# If makeRsaKeys.py is run (instead of imported as a module) call
# the main() function.
if __name__ == '__main__':
   main()

出力

次の出力に示すように、公開キーと秘密キーが生成され、それぞれのファイルに保存されます。

Publickey

RSA暗号暗号化

この章では、RSA暗号暗号化のさまざまな実装とそれに関連する機能に焦点を当てます。 RSA暗号アルゴリズムの実装を実装するには、このpythonファイルを参照または含めることができます。

暗号化アルゴリズムに含まれるモジュールは次のとおりです-

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5
from Crypto import Random
from base64 import b64encode, b64decode
hash = "SHA-256"

セキュリティを向上させるために、ハッシュ値をSHA-256として初期化しました。 関数を使用して、次のコードを使用して新しいキーまたは公開キーと秘密キーのペアを生成します。

def newkeys(keysize):
   random_generator = Random.new().read
   key = RSA.generate(keysize, random_generator)
   private, public = key, key.publickey()
   return public, private
def importKey(externKey):
   return RSA.importKey(externKey)

暗号化のために、RSAアルゴリズムに従う次の機能が使用されます-

def encrypt(message, pub_key):
   cipher = PKCS1_OAEP.new(pub_key)
   return cipher.encrypt(message)

2つのパラメーターは必須です: message および pub_key は公開鍵を参照します。 暗号化には公開鍵が使用され、復号化には秘密鍵が使用されます。

暗号化手順の完全なプログラムは以下に記載されています-

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5
from Crypto import Random
from base64 import b64encode, b64decode
hash = "SHA-256"

def newkeys(keysize):
   random_generator = Random.new().read
   key = RSA.generate(keysize, random_generator)
   private, public = key, key.publickey()
   return public, private

def importKey(externKey):
   return RSA.importKey(externKey)

def getpublickey(priv_key):
   return priv_key.publickey()

def encrypt(message, pub_key):
   cipher = PKCS1_OAEP.new(pub_key)
   return cipher.encrypt(message)

RSA暗号解読

この章は前の章の続きであり、RSAアルゴリズムを使用した暗号化の段階的な実装に続き、それについて詳しく説明します。

暗号テキストを復号化するために使用される機能は次のとおりです-

def decrypt(ciphertext, priv_key):
   cipher = PKCS1_OAEP.new(priv_key)
   return cipher.decrypt(ciphertext)

公開キー暗号化または非対称キー暗号化では、2つの重要な機能、つまり*認証*と*承認*を維持することが重要です。

承認

承認とは、メッセージを送信したのが送信者だけであることを確認するプロセスです。 次のコードはこれを説明します-

def sign(message, priv_key, hashAlg="SHA-256"):
   global hash
   hash = hashAlg
   signer = PKCS1_v1_5.new(priv_key)

   if (hash == "SHA-512"):
      digest = SHA512.new()
   elif (hash == "SHA-384"):
      digest = SHA384.new()
   elif (hash == "SHA-256"):
      digest = SHA256.new()
   elif (hash == "SHA-1"):
      digest = SHA.new()
   else:
      digest = MD5.new()
   digest.update(message)
   return signer.sign(digest)

認証

認証は、以下に説明されている検証方法によって可能です-

def verify(message, signature, pub_key):
   signer = PKCS1_v1_5.new(pub_key)
   if (hash == "SHA-512"):
      digest = SHA512.new()
   elif (hash == "SHA-384"):
      digest = SHA384.new()
   elif (hash == "SHA-256"):
      digest = SHA256.new()
   elif (hash == "SHA-1"):
      digest = SHA.new()
   else:
      digest = MD5.new()
   digest.update(message)
   return signer.verify(digest, signature)

デジタル署名は、送信者と受信者の詳細とともに検証されます。 これにより、セキュリティ上の目的で重量年齢が追加されます。

RSA暗号解読

あなたはRSA暗号解読のために次のコードを使用することができます-

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5
from Crypto import Random
from base64 import b64encode, b64decode
hash = "SHA-256"

def newkeys(keysize):
   random_generator = Random.new().read
   key = RSA.generate(keysize, random_generator)
   private, public = key, key.publickey()
   return public, private

def importKey(externKey):
   return RSA.importKey(externKey)

def getpublickey(priv_key):
   return priv_key.publickey()

def encrypt(message, pub_key):
   cipher = PKCS1_OAEP.new(pub_key)
   return cipher.encrypt(message)

def decrypt(ciphertext, priv_key):
   cipher = PKCS1_OAEP.new(priv_key)
   return cipher.decrypt(ciphertext)

def sign(message, priv_key, hashAlg = "SHA-256"):
   global hash
   hash = hashAlg
   signer = PKCS1_v1_5.new(priv_key)

   if (hash == "SHA-512"):
      digest = SHA512.new()
   elif (hash == "SHA-384"):
      digest = SHA384.new()
   elif (hash == "SHA-256"):
      digest = SHA256.new()
   elif (hash == "SHA-1"):
      digest = SHA.new()
   else:
      digest = MD5.new()
   digest.update(message)
   return signer.sign(digest)

def verify(message, signature, pub_key):
   signer = PKCS1_v1_5.new(pub_key)
   if (hash == "SHA-512"):
      digest = SHA512.new()
   elif (hash == "SHA-384"):
      digest = SHA384.new()
   elif (hash == "SHA-256"):
      digest = SHA256.new()
   elif (hash == "SHA-1"):
      digest = SHA.new()
   else:
      digest = MD5.new()
   digest.update(message)
   return signer.verify(digest, signature)

RSA暗号のハッキング

RSA暗号のハッキングは小さな素数で可能ですが、大きな数で使用する場合は不可能と見なされます。 RSA暗号をハッキングすることが難しい理由を特定する理由は次のとおりです-

  • 通過できるキーが多すぎるため、ブルートフォース攻撃は機能しません。 また、これには多くの時間がかかります。
  • キーは数値であり、その中に文字が含まれていないため、辞書攻撃はRSAアルゴリズムでは機能しません。
  • 単一の暗号化されたブロックがさまざまな文字を表すため、文字の周波数分析を追跡することは非常に困難です。 *RSA暗号をハックするための特定の数学的なトリックはありません。

RSA復号化の方程式は-

M = C^d mod n

小さな素数の助けを借りて、RSA暗号をハッキングしてみることができます。そのためのサンプルコードは以下に記載されています-

def p_and_q(n):
   data = []
   for i in range(2, n):
      if n % i == 0:
         data.append(i)
   return tuple(data)

def euler(p, q):
   return (p - 1)* (q - 1)

def private_index(e, euler_v):
   for i in range(2, euler_v):
      if i *e % euler_v == 1:
         return i

def decipher(d, n, c):
   return c* * d % n
    def main():
      e = int(input("input e: "))
      n = int(input("input n: "))
      c = int(input("input c: "))

      # t = 123
      # private key = (103, 143)
      p_and_q_v = p_and_q(n)
      # print("[p_and_q]: ", p_and_q_v)
      euler_v = euler(p_and_q_v[0], p_and_q_v[1])

      # print("[euler]: ", euler_v)
      d = private_index(e, euler_v)
      plain = decipher(d, n, c)
      print("plain: ", plain)
if __name__ == "__main__":
   main()

出力

上記のコードは、次の出力を生成します-

RSA暗号のハッキング