Cryptography With Python 简明教程

Cryptography with Python - Quick Guide

Cryptography with Python - Overview

密码学是两个用户通过编码信息进行通信的艺术。密码学的科学以基本动机出现,即为从一方转移到另一方的机密信息提供安全性。

Cryptography is the art of communication between two users via coded messages. The science of cryptography emerged with the basic motive of providing security to the confidential messages transferred from one party to another.

密码学被定义为将信息隐藏起来以引入信息安全性中公认的隐私和机密的艺术和科学。

Cryptography is defined as the art and science of concealing the message to introduce privacy and secrecy as recognized in information security.

Terminologies of Cryptography

这里解释了密码学中经常使用的术语 -

The frequently used terms in cryptography are explained here −

Plain Text

明文消息是可读且所有用户均能理解的文本。明文是进行密码操作的信息。

The plain text message is the text which is readable and can be understood by all users. The plain text is the message which undergoes cryptography.

Cipher Text

密文是在明文上应用密码操作后获得的信息。

Cipher text is the message obtained after applying cryptography on plain text.

Encryption

将明文转换为密文的过程称为加密。它也称为编码。

The process of converting plain text to cipher text is called encryption. It is also called as encoding.

Decryption

将密文转换为明文的过程称为解密。它也称为解码。

The process of converting cipher text to plain text is called decryption. It is also termed as decoding.

给出的图表显示了密码学完整过程的说明 -

The diagram given below shows an illustration of the complete process of cryptography −

encryption

Characteristics of Modern Cryptography

现代密码学的基本特征如下 -

The basic characteristics of modern cryptography are as follows −

  1. It operates on bit sequences.

  2. It uses mathematical algorithms for securing the information.

  3. It requires parties interested in secure communication channel to achieve privacy.

Double Strength Encryption

双重加密,也称为多重加密,是指使用相同或不同的算法/模式对已加密文本进行一次或多次加密的过程。

Double strength encryption, also called as multiple encryption, is the process of encrypting an already encrypted text one or more times, either with the same or different algorithm/pattern.

双重加密的其他名称包括级联加密或级联密码。

The other names for double strength encryption include cascade encryption or cascade ciphering.

Levels of Double Strength Encryption

双重加密包括在此处解释的各种级别的加密 -

Double strength encryption includes various levels of encryption that are explained here under −

First layer of encryption

使用哈希算法和对称密钥从原始可读消息中生成密文。稍后会借助非对称密钥对称密钥进行加密。对此模式的最佳说明是将密文的哈希摘要合并到一个胶囊中。接收方将首先计算摘要,然后解密文本以验证文本在两者之间未被篡改。

The cipher text is generated from the original readable message using hash algorithms and symmetric keys. Later symmetric keys are encrypted with the help of asymmetric keys. The best illustration for this pattern is combining the hash digest of the cipher text into a capsule. The receiver will compute the digest first and later decrypt the text in order to verify that text is not tampered in between.

Second layer of encryption

第二层加密是使用相同或不同算法为密文添加一层的过程。通常,为此使用 32 位字符长的对称密码。

Second layer of encryption is the process of adding one more layer to cipher text with same or different algorithm. Usually, a 32-bit character long symmetric password is used for the same.

Third layer of encryption

在此过程中,加密胶囊通过 SSL/TLS 连接传输到通信方。

In this process, the encrypted capsule is transmitted via SSL/TLS connection to the communication partner.

下图直观地显示了双重加密过程 −

The following diagram shows double encryption process pictorially −

strength encryption

Hybrid Cryptography

混合密码术是通过包括每种密码的好处,将不同类型的多个密码组合在一起的过程。通常遵循一种通用方法来为对称密码生成随机密钥,然后通过非对称密钥密码术加密此密钥。

Hybrid cryptography is the process of using multiple ciphers of different types together by including benefits of each of the cipher. There is one common approach which is usually followed to generate a random secret key for a symmetric cipher and then encrypt this key via asymmetric key cryptography.

由于这种模式,原始消息本身使用对称密码加密,然后使用密钥。接收方收到消息后,首先使用自己的私钥使用密钥解密消息,然后使用指定的密钥解密消息。

Due to this pattern, the original message itself is encrypted using the symmetric cipher and then using secret key. The receiver after receiving the message decrypts the message using secret key first, using his/her own private key and then uses the specified key to decrypt the message.

Python Overview and Installation

Python 是一种开源脚本语言,它高级、直譯、互动且面向对象的。它被设计为高度可读。Python 语言的语法易于理解且经常使用英语关键字。

Python is an open source scripting language which is high-level, interpreted, interactive and object-oriented. It is designed to be highly readable. The syntax of Python language is easy to understand and uses English keywords frequently.

Features of Python Language

Python 提供以下主要功能 −

Python provides the following major features −

Interpreted

Python 在运行时使用解释器处理。在执行之前无需编译程序。它类似于 PERL 和 PHP。

Python is processed at runtime using the interpreter. There is no need to compile a program before execution. It is similar to PERL and PHP.

Object-Oriented

Python 遵循面向对象样式和设计模式。它包括类定义,具有封装和多态性等各种功能。

Python follows object-oriented style and design patterns. It includes class definition with various features like encapsulation and polymorphism.

Key Points of Python Language

Python 编程语言的关键点如下 −

The key points of Python programming language are as follows −

  1. It includes functional and structured programming and methods as well as object oriented programming methods.

  2. It can be used as a scripting language or as a programming language.

  3. It includes automatic garbage collection.

  4. It includes high-level dynamic data types and supports various dynamic type checking.

  5. Python includes a feature of integration with C, C++ and languages like Java.

Python 语言的下载链接如下 − www.python.org/downloads 它包括 Windows、MacOS 和 Linux 发行版等各种操作系统的软件包。

The download link for Python language is as follows − www.python.org/downloadsIt includes packages for various operating systems like Windows, MacOS and Linux distributions.

python download

Python Strings

字符串的基本声明如下所示 −

The basic declaration of strings is shown below −

str = 'Hello World!'

Python Lists

Python 列表可以声明为复合数据类型,用逗号分隔并用方括号 ([]) 括起来。

The lists of python can be declared as compound data types, separated by commas and enclosed within square brackets ([]).

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

Python Tuples

元组是 Python 的动态数据类型,由用逗号分隔的多个值组成。元组用括号括起来。

A tuple is dynamic data type of Python which consists of number of values separated by commas. Tuples are enclosed with parentheses.

tinytuple = (123, 'john')

Python Dictionary

Python 字典是一种哈希表。字典键几乎可以是 Python 的任何数据类型,通常是数字或字符串。

Python dictionary is a type of hash table. A dictionary key can be almost any data type of Python, which are usually numbers or strings.

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

Cryptography Packages

Python 包含一个名为 cryptography 的软件包,该软件包提供加密算法和基础函数。它支持 Python 2.7、Python 3.4+和 PyPy 5.3+。通过以下命令完成 cryptography 软件包的基本安装 −

Python includes a package called cryptography which provides cryptographic recipes and primitives. It supports Python 2.7, Python 3.4+, and PyPy 5.3+. The basic installation of cryptography package is achieved through following command −

pip install cryptography

提供了许多带有高级秘方和低级接口的软件包,可用于 symmetric ciphersmessage digestskey derivation functions. 等通用加密算法。

There are various packages with both high level recipes and low level interfaces to common cryptographic algorithms such as symmetric ciphers, message digests and key derivation functions.

在整个教程中,我们将使用 Python 的各种软件包来实现加密算法。

Throughout this tutorial, we will be using various packages of Python for implementation of cryptographic algorithms.

Cryptography with Python - Reverse Cipher

上一章概述了如何在本地计算机上安装 Python。在本章中,你将详细了解反向密码及其编码。

The previous chapter gave you an overview of installation of Python on your local computer. In this chapter you will learn in detail about reverse cipher and its coding.

Algorithm of Reverse Cipher

反向密码算法具有以下特征:

The algorithm of reverse cipher holds the following features −

  1. Reverse Cipher uses a pattern of reversing the string of plain text to convert as cipher text.

  2. The process of encryption and decryption is same.

  3. To decrypt cipher text, the user simply needs to reverse the cipher text to get the plain text.

Drawback

  • 反向密码的主要缺点是它非常弱。黑客可以轻松破解密文以获取原始消息。因此,反向密码不被认为是维护安全通信通道的良好选择。

The major drawback of reverse cipher is that it is very weak. A hacker can easily break the cipher text to get the original message. Hence, reverse cipher is not considered as good option to maintain secure communication channel,.

dawback

Example

考虑一个示例,该示例中将使用反向密码算法实现语句 This is program to explain reverse cipher 。以下 Python 代码使用该算法来获取输出。

Consider an example where the statement This is program to explain reverse cipher is to be implemented with reverse cipher algorithm. The following python code uses the algorithm to obtain the output.

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)

Output

你可以在以下图像中看到反转后的文本,即输出:

You can see the reversed text, that is the output as shown in the following image −

output

Explanation

  1. Plain text is stored in the variable message and the translated variable is used to store the cipher text created.

  2. The length of plain text is calculated using for loop and with help of index number. The characters are stored in cipher text variable translated which is printed in the last line.

Cryptography with Python - Caesar Cipher

在上一章中,我们已经处理了反向密码。本章详细介绍了凯撒密码。

In the last chapter, we have dealt with reverse cipher. This chapter talks about Caesar cipher in detail.

Algorithm of Caesar Cipher

凯撒密码算法具有以下特征:

The algorithm of Caesar cipher holds the following features −

  1. Caesar Cipher Technique is the simple and easy method of encryption technique.

  2. It is simple type of substitution cipher.

  3. Each letter of plain text is replaced by a letter with some fixed number of positions down with alphabet.

  • 以下图表描述了凯撒密码算法实现的工作原理:

The following diagram depicts the working of Caesar cipher algorithm implementation −

algorithm caesar cipher

凯撒密码算法的程序实现如下:

The program implementation of Caesar cipher algorithm is as follows −

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)

Output

你可以看到凯撒密码,即下图所示的输出−

You can see the Caesar cipher, that is the output as shown in the following image −

caesar cipher

Explanation

一次遍历一个纯文本字符。

The plain text character is traversed one at a time.

  1. For each character in the given plain text, transform the given character as per the rule depending on the procedure of encryption and decryption of text.

  2. After the steps is followed, a new string is generated which is referred as cipher text.

Hacking of Caesar Cipher Algorithm

密文可以用各种可能性破解。其中一种可能性是 Brute Force Technique, ,它涉及尝试每个可能的解密密钥。此技术不需要太多精力,对于黑客来说相对简单。

The cipher text can be hacked with various possibilities. One of such possibility is Brute Force Technique, which involves trying every possible decryption key. This technique does not demand much effort and is relatively simple for a hacker.

破解凯撒密码算法的程序实现如下−

The program implementation for hacking Caesar cipher algorithm is as follows −

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))

考虑在前一示例中加密的密文。然后,使用密钥并使用暴力攻击技术,可能的破解方法的输出如下−

Consider the cipher text encrypted in the previous example. Then, the output with possible hacking methods with the key and using brute force attack technique is as follows −

hacking caesar cipher

Cryptography with Python - ROT13 Algorithm

到目前为止,您已经了解了反向密码和凯撒密码算法。现在,我们来讨论 ROT13 算法及其实现。

Till now, you have learnt about reverse cipher and Caesar cipher algorithms. Now, let us discuss the ROT13 algorithm and its implementation.

Explanation of ROT13 Algorithm

ROT13 密码指的是缩写 Rotate by 13 places 。它凯撒密码的一个特例,其中移位始终为 13。每封信都移位 13 位,以加密或解密消息。

ROT13 cipher refers to the abbreviated form Rotate by 13 places. It is a special case of Caesar Cipher in which shift is always 13. Every letter is shifted by 13 places to encrypt or decrypt the message.

Example

下图形象地说明了 ROT13 算法流程 −

The following diagram explains the ROT13 algorithm process pictorially −

rot

Program Code

ROT13算法的程序实现如下 -

The program implementation of ROT13 algorithm is as follows −

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 输出 -

You can see the ROT13 output as shown in the following image −

rot13

Drawback

ROT13算法使用13位移。因此,以相反方式位移字符非常容易解密密文。

The ROT13 algorithm uses 13 shifts. Therefore, it is very easy to shift the characters in the reverse manner to decrypt the cipher text.

Analysis of ROT13 Algorithm

ROT13加密算法被认为是凯撒加密的特殊情况。这并不是一种非常安全的算法,可以通过频率分析或仅仅尝试可能的 25 个密钥轻松破解,而 ROT13 可以通过位移 13 位进行破解。因此,它没有任何实际用途。

ROT13 cipher algorithm is considered as special case of Caesar Cipher. It is not a very secure algorithm and can be broken easily with frequency analysis or by just trying possible 25 keys whereas ROT13 can be broken by shifting 13 places. Therefore, it does not include any practical use.

Transposition Cipher

移位密码是一种密码算法,其中将明文中的字母顺序重新排列以形成密文。在此过程中,不包括实际的明文字母。

Transposition Cipher is a cryptographic algorithm where the order of alphabets in the plaintext is rearranged to form a cipher text. In this process, the actual plain text alphabets are not included.

Example

移动密码的一个简单示例是 columnar transposition cipher ,其中明文中的每个字符都以指定的字母宽度水平书写。密文是垂直书写的,这会创建一个完全不同的密文。

A simple example for a transposition cipher is columnar transposition cipher where each character in the plain text is written horizontally with specified alphabet width. The cipher is written vertically, which creates an entirely different cipher text.

考虑明文 hello world ,让我们应用如下所示的简单列移位技术

Consider the plain text hello world, and let us apply the simple columnar transposition technique as shown below

columnar transposition

明文字符水平放置,并且密文以垂直格式创建为 : holewdlo lr. 。现在,接收者必须使用相同的表格将密文解密为明文。

The plain text characters are placed horizontally and the cipher text is created with vertical format as : holewdlo lr. Now, the receiver has to use the same table to decrypt the cipher text to plain text.

Code

以下程序代码演示了列移位技术的简单实现−

The following program code demonstrates the basic implementation of columnar transposition technique −

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'))

Explanation

  1. Using the function split_len(), we can split the plain text characters, which can be placed in columnar or row format.

  2. encode method helps to create cipher text with key specifying the number of columns and prints the cipher text by reading characters through each column.

Output

列移位技术的基本实现的程序代码提供了以下输出−

The program code for the basic implementation of columnar transposition technique gives the following output −

columnar transposition technique

Note − 当执行移位技术时,密码分析人员观察到密码安全显著提高。他们还注意到,使用相同的移位密码重新加密密文会产生更好的安全性。

Note − Cryptanalysts observed a significant improvement in crypto security when transposition technique is performed. They also noted that re-encrypting the cipher text using same transposition cipher creates better security.

Encryption of Transposition Cipher

在上一章中,我们学习了移位密码。在本章中,让我们讨论其加密。

In the previous chapter, we have learnt about Transposition Cipher. In this chapter, let us discuss its encryption.

Pyperclip

pyperclip 插件在 Python 编程语言中的主要用法是执行跨平台模块以将文本复制并粘贴到剪贴板中。你可以使用以下命令安装 Python pyperclip 模块

The main usage of pyperclip plugin in Python programming language is to perform cross platform module for copying and pasting text to the clipboard. You can install python pyperclip module using the command as shown

pip install pyperclip

如果系统中已存在该需求,则你可以看到以下输出−

If the requirement already exists in the system, you can see the following output −

pyperclip

Code

以下是使用 pyperclip 作为主模块的 Python 置换密码加密代码:

The python code for encrypting transposition cipher in which pyperclip is the main module is as shown below −

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()

Output

pyperclip 作为主模块的置换密码加密程序代码给出以下输出:

The program code for encrypting transposition cipher in which pyperclip is the main module gives the following output −

encrypting transposition

Explanation

  1. The function main() calls the encryptMessage() which includes the procedure for splitting the characters using len function and iterating them in a columnar format.

  2. The main function is initialized at the end to get the appropriate output.

Decryption of Transposition Cipher

在本章中,将学习解密置换密码的程序。

In this chapter, you will learn the procedure for decrypting the transposition cipher.

Code

观察以下代码以更好地理解如何解密置换密码。消息 Transposition Cipher 的密文和密钥 6 被获取为 Toners raiCntisippoh.

Observe the following code for a better understanding of decrypting a transposition cipher. The cipher text for message Transposition Cipher with key as 6 is fetched as 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()

Explanation

密文和提到的密钥是作为输入参数采取的两个值,用于通过逆向技术解码或解密密文,即将字符放在列格式中并以水平方式读取它们。

The cipher text and the mentioned key are the two values taken as input parameters for decoding or decrypting the cipher text in reverse technique by placing characters in a column format and reading them in a horizontal manner.

可以使用以下代码段将字母放在列格式中,然后组合或连接它们:

You can place letters in a column format and later combined or concatenate them together using the following piece of code −

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)

Output

解密置换密码的程序代码给出以下输出:

The program code for decrypting transposition cipher gives the following output −

decrypting transposition

Encryption of files

在 Python 中,可以在传输到通信信道之前对文件进行加密和解密。为此,必须使用插件 PyCrypto 。可以使用以下给出的命令安装此插件。

In Python, it is possible to encrypt and decrypt files before transmitting to a communication channel. For this, you will have to use the plugin PyCrypto. You can installation this plugin using the command given below.

pip install pycrypto
pycrypto

Code

使用密码保护对文件进行加密的程序代码如下所示:

The program code for encrypting the file with password protector is mentioned below −

# =================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()

可以使用以下命令执行加密过程和密码:

You can use the following command to execute the encryption process along with password −

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

Output

执行上述代码时,可以看到以下输出:

You can observe the following output when you execute the code given above −

encryption process

Explanation

密码使用 MD5 哈希算法生成,这些值存储在 Windows 系统的简单安全备份文件中,其中包括以下显示的值:

The passwords are generated using MD5 hash algorithm and the values are stored in simply safe backup files in Windows system, which includes the values as displayed below −

explanation

Decryption of files

在本章中,让我们讨论使用 Python 对密码学中的文件进行解密。请注意,对于解密过程,我们将遵循相同的过程,但不是指定输出路径,而是关注输入路径或加密的必要文件。

In this chapter, let us discuss decryption of files in cryptography using Python. Note that for decryption process, we will follow the same procedure, but instead of specifying the output path, we will focus on input path or the necessary file which is encrypted.

Code

以下是使用 Python 对密码学中的文件进行解密的示例代码:

The following is a sample code for decrypting files in cryptography using 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()

可以使用以下命令执行上述代码:

You can use the following command for executing the above code −

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

Output

执行上述命令时,可以看到以下代码:

You can observe the following code when you execute the command shown above −

decrypting

Note - 输出指定加密前和解密后的哈希值,这会记录加密相同的文件并且该过程成功。

Note − The output specifies the hash values before encryption and after decryption, which keeps a note that the same file is encrypted and the process was successful.

Base64 Encoding and Decoding

Base64 编码将二进制数据转换为文本格式,该格式通过用户可以安全处理文本的通信通道传输。Base64 也称为 Privacy enhanced Electronic mail (PEM) ,主要用于电子邮件加密过程。

Base64 encoding converts the binary data into text format, which is passed through communication channel where a user can handle text safely. Base64 is also called as Privacy enhanced Electronic mail (PEM) and is primarily used in email encryption process.

Python 包含一个名为 BASE64 的模块,其中包括两个主要函数,如下所示:-

Python includes a module called BASE64 which includes two primary functions as given below −

  1. base64.decode(input, output) − It decodes the input value parameter specified and stores the decoded output as an object.

  2. Base64.encode(input, output) − It encodes the input value parameter specified and stores the decoded output as an object.

Program for Encoding

可以使用以下代码段执行 base64 编码:-

You can use the following piece of code to perform base64 encoding −

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

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

Output

base64 编码的代码给你以下输出:-

The code for base64 encoding gives you the following output −

base64

Program for Decoding

可以使用以下代码段执行 base64 解码:-

You can use the following piece of code to perform base64 decoding −

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

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

Output

base64 解码的代码给你以下输出:-

The code for base64 decoding gives you the following output −

base64 decoding

Difference between ASCII and base64

在对数据进行编码时,使用 ASCII 和 base64 时,你可以观察到以下区别:-

You can observe the following differences when you work on ASCII and base64 for encoding data −

  1. When you encode text in ASCII, you start with a text string and convert it to a sequence of bytes.

  2. When you encode data in Base64, you start with a sequence of bytes and convert it to a text string.

Drawback

Base64 算法通常用于在数据库中存储密码。主要缺点是每个解码后的单词都可以通过任何在线工具轻松编码,入侵者可以轻松获取信息。

Base64 algorithm is usually used to store passwords in database. The major drawback is that each decoded word can be encoded easily through any online tool and intruders can easily get the information.

Cryptography with Python - XOR Process

在本章节中,让我们了解 XOR 过程及其在 Python 中的编码。

In this chapter, let us understand the XOR process along with its coding in Python.

Algorithm

加密和解密的 XOR 算法将明文转换为 ASCII 字节格式,并使用 XOR 过程将其转换为指定的字节。它为用户提供以下优势:-

XOR algorithm of encryption and decryption converts the plain text in the format ASCII bytes and uses XOR procedure to convert it to a specified byte. It offers the following advantages to its users −

  1. Fast computation

  2. No difference marked in left and right side

  3. Easy to understand and analyze

Code

可以使用以下代码段执行 XOR 过程:-

You can use the following piece of code to perform XOR process −

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)

Output

XOR 过程的代码给你以下输出:-

The code for XOR process gives you the following output −

xor

Explanation

  1. The function xor_crypt_string() includes a parameter to specify mode of encode and decode and also the string value.

  2. The basic functions are taken with base64 modules which follows the XOR procedure/ operation to encrypt or decrypt the plain text/ cipher text.

Note − XOR 加密用于加密数据,并且很难通过暴力攻击方法(这是一种通过生成随机加密密钥来匹配正确的密码文本)破解。

Note − XOR encryption is used to encrypt data and is hard to crack by brute-force method, that is by generating random encrypting keys to match with the correct cipher text.

Multiplicative Cipher

在使用凯撒密码技术时,加密和解密符号涉及使用简单的基本加法或减法程序将值转换为数字。

While using Caesar cipher technique, encrypting and decrypting symbols involves converting the values into numbers with a simple basic procedure of addition or subtraction.

如果使用乘法转换为密码文本,则称为 wrap-around 情况。请将字母和关联的数字考虑为以下所示−

If multiplication is used to convert to cipher text, it is called a wrap-around situation. Consider the letters and the associated numbers to be used as shown below −

associated numbers

这些数字将用于乘法程序,关联密钥为 7。在这种情况下用于生成乘法密码的基本公式如下−

The numbers will be used for multiplication procedure and the associated key is 7. The basic formula to be used in such a scenario to generate a multiplicative cipher is as follows −

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

通过输出获取的数字映射到上面提到的表格中,并且相应的字母被视为加密字母。

The number fetched through output is mapped in the table mentioned above and the corresponding letter is taken as the encrypted letter.

encrypted letter

乘法密码在 Python 中的基本调制函数如下−

The basic modulation function of a multiplicative cipher in Python is as follows −

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

Note − 乘法密码的优点是它可以使用 8,953,851 之类的非常大的密钥。对于计算机而言,通过九百万个密钥中的大多数进行暴力攻击需要相当长的时间。

Note − The advantage with a multiplicative cipher is that it can work with very large keys like 8,953,851. It would take quite a long time for a computer to brute-force through a majority of nine million keys.

Cryptography with Python - Affine Cipher

Affine 密码是乘法密码和凯撒密码算法的组合。Affine 密码的基本实现如下图所示−

Affine Cipher is the combination of Multiplicative Cipher and Caesar Cipher algorithm. The basic implementation of affine cipher is as shown in the image below −

affine cipher

在本章中,我们将通过创建对应的类来实现 Affine 密码,该类包括用于加密和解密的两个基本函数。

In this chapter, we will implement affine cipher by creating its corresponding class that includes two basic functions for encryption and decryption.

Code

您可以使用以下代码来实现 Affine 密码−

You can use the following code to implement an affine cipher −

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')

Output

当您实现 Affine 密码时,可以看到以下输出−

You can observe the following output when you implement an affine cipher −

affine

输出显示了纯文本消息的加密消息 Affine Cipher 以及作为输入发送的消息的解密消息 abcdefg.

The output displays the encrypted message for the plain text message Affine Cipher and decrypted message for the message sent as input abcdefg.

Hacking Monoalphabetic Cipher

在本章中,您将了解单表字母加密及其使用 Python 进行破解。

In this chapter, you will learn about monoalphabetic cipher and its hacking using Python.

Monoalphabetic Cipher

单表字母加密对加密整个消息使用固定的替换。此处显示了使用带有 JSON 对象的 Python 字典的单表字母加密−

A Monoalphabetic cipher uses a fixed substitution for encrypting the entire message. A monoalphabetic cipher using a Python dictionary with JSON objects is shown here −

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 对象中值的关联字母来加密字母。以下程序创建了一个单表字母程序,作为一个类表示,其中包括所有加密和解密的函数。

With help of this dictionary, we can encrypt the letters with the associated letters as values in JSON object. The following program creates a monoalphabetic program as a class representation which includes all the functions of encryption and decryption.

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)
   )

此文件稍后被调用来实现单表字母加密的加密和解密过程,如下所示−

This file is called later to implement the encryption and decryption process of Monoalphabetic cipher which is mentioned as below −

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)

Output

当您实现上面给出的代码时,可以看到以下输出−

You can observe the following output when you implement the code given above −

monoalphabetic

因此,您可以破解具有指定键值对的单表字母加密,该键值对将密码文本破解为实际的明文。

Thus, you can hack a monoalphabetic cipher with specified key value pair which cracks the cipher text to actual plain text.

Simple Substitution Cipher

简单替换密码是最常用的密码,包括用于将每个明文字符替换为每个密文字符的算法。在此过程中,与凯撒密码算法相比,字母顺序混乱。

Simple substitution cipher is the most commonly used cipher and includes an algorithm of substituting every plain text character for every cipher text character. In this process, alphabets are jumbled in comparison with Caesar cipher algorithm.

Example

简单替换密码的密钥通常由 26 个字母组成。示例密钥为 −

Keys for a simple substitution cipher usually consists of 26 letters. An example key is −

plain alphabet : abcdefghijklmnopqrstuvwxyz
cipher alphabet: phqgiumeaylnofdxjkrcvstzwb

使用上述密钥的一个示例加密为 −

An example encryption using the above key is−

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

以下代码显示了一个实现简单替换密码的程序−

The following code shows a program to implement simple substitution cipher −

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()

Output

当您实现上面给出的代码时,可以看到以下输出−

You can observe the following output when you implement the code given above −

simple substitution

Testing of Simple Substitution Cipher

在本章中,我们将专注于使用各种方法测试替换密码,这有助于生成随机字符串,如下所示 −

In this chapter, we will focus on testing substitution cipher using various methods, which helps to generate random strings as given below −

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()

Output

您可以观察到作为随机生成字符串的输出,这有助于生成随机明文消息,如下所示 −

You can observe the output as randomly generated strings which helps in generating random plain text messages, as shown below −

strings

测试成功完成之后,我们可以观察到输出消息 “ Substitution test passed!.

After the test is successfully completed, we can observe the output message Substitution test passed!.

substitution

因此,您可以以系统的方式破解替换密码。

Thus, you can hack a substitution cipher in the systematic manner.

Decryption of Simple Substitution Cipher

在本章中,您可以了解替换密码的简单实现,该实现根据简单替换密码技术中使用的逻辑显示加密和解密消息。这可以认为是编码的另一种方法。

In this chapter, you can learn about simple implementation of substitution cipher which displays the encrypted and decrypted message as per the logic used in simple substitution cipher technique. This can be considered as an alternative approach of coding.

Code

您可以使用以下代码执行使用简单替换密码的解密 −

You can use the following code to perform decryption using simple substitution cipher −

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')

Output

上面的代码给出了如下所示的输出 −

The above code gives you the output as shown here −

implementation

Python Modules of Cryptography

在本章中,您将详细了解 Python 中加密的各种模块。

In this chapter, you will learn in detail about various modules of cryptography in Python.

Cryptography Module

它包括所有配方和原语,并提供 Python 中的高级编码接口。您可以使用以下命令安装加密模块 −

It includes all the recipes and primitives, and provides a high level interface of coding in Python. You can install cryptography module using the following command −

pip install cryptography
pip install

Code

您可以使用以下代码实现加密模块 −

You can use the following code to implement the cryptography module −

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)

Output

上面给出的代码生成以下输出了 −

The code given above produces the following output −

authentication

这里给出的代码用于验证密码并创建其哈希。它还包括用于验证用于身份验证目的的密码的逻辑。

The code given here is used to verify the password and creating its hash. It also includes logic for verifying the password for authentication purpose.

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')

Output

Scenario 1 − 如果您输入了正确的密码,您可以找到以下输出 −

Scenario 1 − If you have entered a correct password, you can find the following output −

correct password

Scenario 2 − 如果我们输入错误密码,您可以找到以下输出 −

Scenario 2 − If we enter wrong password, you can find the following output −

wrong password

Explanation

Hashlib 包用于将密码存储在数据库中。在此程序中,使用了 “ salt ”,它在实现哈希函数之前向密码字符串添加随机序列。

Hashlib package is used for storing passwords in a database. In this program, salt is used which adds a random sequence to the password string before implementing the hash function.

Understanding Vignere Cipher

韦格纳密码加入了恺撒密码算法的微调,用于加密和解密。韦格纳密码与恺撒密码算法的工作方式相似,但有一个主要区别:恺撒密码包括一个字符偏移算法,而韦格纳密码则包括一个有多个字母偏移的密匙。

Vignere Cipher includes a twist with Caesar Cipher algorithm used for encryption and decryption. Vignere Cipher works similar to Caesar Cipher algorithm with only one major distinction: Caesar Cipher includes algorithm for one-character shift, whereas Vignere Cipher includes key with multiple alphabets shift.

Mathematical Equation

对于加密,数学方程式如下:

For encryption the mathematical equation is as follows −

E_{k}\left(M{ {i{}}} \right ) = \left ( M {i}+K_{i}\right)\;\;\;mod\;\;26

E_{k}\left ( M{{i{}}} \right ) = \left ( M{i}+K_{i} \right )\;\;\; mod \;\; 26

对于解密,数学方程式如下:

For decryption the mathematical equation is as follows −

D_{k}\left(C{ {i{}}} \right ) = \left ( C {i}-K_{i}\right)\;\;\;mod\;\;26

D_{k}\left ( C{{i{}}} \right ) = \left ( C{i}-K_{i} \right )\;\;\; mod \;\; 26

韦格纳密码使用多套代换,因此也称为 polyalphabetic cipher 。韦格纳密码将使用字母密匙,而非数字密匙表示法:字母 A 将用于密匙 0,字母 B 将用于密匙 1,依次类推。加密过程前后字母的数字如下所示:

Vignere cipher uses more than one set of substitutions, and hence it is also referred as polyalphabetic cipher. Vignere Cipher will use a letter key instead of a numeric key representation: Letter A will be used for key 0, letter B for key 1 and so on. Numbers of the letters before and after encryption process is shown below −

polyalphabetic cipher

基于韦格纳密匙长度的密钥可能组合数目如下,它给出了韦格纳密码算法的安全性:

The possible combination of number of possible keys based on Vignere key length is given as follows, which gives the result of how secure is Vignere Cipher Algorithm −

Vignere key length

Vignere Tableau

韦格纳密码使用的表如下图所示:

The tableau used for Vignere cipher is as shown below −

vignere tableau

Implementing Vignere Cipher

在本章中,让我们了解韦格纳密码的实现方式。考虑要对文本 This is basic implementation of Vignere Cipher 进行编码,所使用的密钥为 PIZZA.

In this chapter, let us understand how to implement Vignere cipher. Consider the text This is basic implementation of Vignere Cipher is to be encoded and the key used is PIZZA.

Code

可以使用以下代码在 Python 中实现韦格纳密码:

You can use the following code to implement a Vignere cipher in Python −

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()

Output

当您实现上面给出的代码时,可以看到以下输出−

You can observe the following output when you implement the code given above −

secure encryption mode

破解韦格纳密码的可能组合近乎不可能。因此,它被认为是一种安全的加密模式。

The possible combinations of hacking the Vignere cipher is next to impossible. Hence, it is considered as a secure encryption mode.

One Time Pad Cipher

一次性密文是一种韦格纳密码,它包括以下功能:

One-time pad cipher is a type of Vignere cipher which includes the following features −

  1. It is an unbreakable cipher.

  2. The key is exactly same as the length of message which is encrypted.

  3. The key is made up of random symbols.

  4. As the name suggests, key is used one time only and never used again for any other message to be encrypted.

因此,加密消息对于密码分析员而言容易受到攻击。用于一次性密文的密匙称为 pad ,因为它被印在纸张上。

Due to this, encrypted message will be vulnerable to attack for a cryptanalyst. The key used for a one-time pad cipher is called pad, as it is printed on pads of paper.

Why is it Unbreakable?

密匙无法破解,原因是以下特性:

The key is unbreakable owing to the following features −

  1. The key is as long as the given message.

  2. The key is truly random and specially auto-generated.

  3. Key and plain text calculated as modulo 10/26/2.

  4. Each key should be used once and destroyed by both sender and receiver.

  5. There should be two copies of key: one with the sender and other with the receiver.

Encryption

要加密一封信件,用户需要在纯文本下方书写密钥。纯文本信件放置在顶部,密钥信件放置在左侧。这两个信件之间的横截面为纯文本。如下例中所述:

To encrypt a letter, a user needs to write a key underneath the plaintext. The plaintext letter is placed on the top and the key letter on the left. The cross section achieved between two letters is the plain text. It is described in the example below −

otp

Decryption

要解密一封信件,用户在左侧取得密钥信件,并在该行中查找密文信件。纯文本信件放置在该列的顶部,用户可以在顶部找到密文信件。

To decrypt a letter, user takes the key letter on the left and finds cipher text letter in that row. The plain text letter is placed at the top of the column where the user can find the cipher text letter.

Implementation of One Time Pad Cipher

Python 包含一个 hacky 实现模块,用于 one-time-pad 密码实现。该软件包名称称为一次性密码本,其中包含一个命令行加密工具,该工具使用类似一次性密码本密码算法的加密机制。

Python includes a hacky implementation module for one-time-pad cipher implementation. The package name is called One-Time-Pad which includes a command line encryption tool that uses encryption mechanism similar to the one-time pad cipher algorithm.

Installation

您可以使用以下命令安装此模块:

You can use the following command to install this module −

pip install onetimepad

如果您想从命令行使用它,请运行以下命令:

If you wish to use it from the command-line, run the following command −

onetimepad
pip

Code

以下代码有助于生成一次性密码本密码:

The following code helps to generate a one-time pad cipher −

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)

Output

当您运行上面给出的代码时,您可以观察到以下输出:

You can observe the following output when you run the code given above −

pip output

Note - 如果密钥的长度小于消息(纯文本)的长度,那么加密的消息非常容易破解。

Note − The encrypted message is very easy to crack if the length of the key is less than the length of message (plain text).

在任何情况下,密钥都不一定是随机的,这使得一次性密码本密码成为一种有价值的工具。

In any case, the key is not necessarily random, which makes one-time pad cipher as a worth tool.

Symmetric and Asymmetric Cryptography

在本章中,让我们详细讨论对称和非对称密码术。

In this chapter, let us discuss in detail about symmetric and asymmetric cryptography.

Symmetric Cryptography

在此类型中,加密和解密过程使用相同的密钥。它也被称为 secret key cryptography 。对称密码术的主要功能如下:

In this type, the encryption and decryption process uses the same key. It is also called as secret key cryptography. The main features of symmetric cryptography are as follows −

  1. It is simpler and faster.

  2. The two parties exchange the key in a secure way.

Drawback

对称密码术的主要缺点是,如果密钥泄漏给入侵者,则消息可以被轻松地更改,这被视为风险因素。

The major drawback of symmetric cryptography is that if the key is leaked to the intruder, the message can be easily changed and this is considered as a risk factor.

Data Encryption Standard (DES)

最流行的对称密钥算法是数据加密标准 (DES),且 Python 包含一个软件包,该软件包包括 DES 算法背后的逻辑。

The most popular symmetric key algorithm is Data Encryption Standard (DES) and Python includes a package which includes the logic behind DES algorithm.

Installation

Python 中安装 DES 包 pyDES 的命令为:

The command for installation of DES package pyDES in Python is −

pip install pyDES
pydes

DES 算法的简单程序实现如下:

Simple program implementation of DES algorithm is as follows −

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

它调用变量 padmode ,它获取所有 DES 算法实现所需的包,并以特定方式执行加密和解密。

It calls for the variable padmode which fetches all the packages as per DES algorithm implementation and follows encryption and decryption in a specified manner.

Output

以下为上述代码运行后的输出:

You can see the following output as a result of the code given above −

des algorithm

Asymmetric Cryptography

它也被称为 public key cryptography. 。它的工作方式与对称加密相反。这意味着它需要两个密钥:一个用于加密,另一个用于解密。公钥用于加密,而私钥用于解密。

It is also called as public key cryptography. It works in the reverse way of symmetric cryptography. This implies that it requires two keys: one for encryption and other for decryption. The public key is used for encrypting and the private key is used for decrypting.

Drawback

  1. Due to its key length, it contributes lower encryption speed.

  2. Key management is crucial.

以下 Python 程序代码演示了如何使用 RSA 算法和实现执行非对称加密:

The following program code in Python illustrates the working of asymmetric cryptography using RSA algorithm and its implementation −

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))

Output

当您执行上述代码时,可以找到以下输出:

You can find the following output when you execute the code given above −

rsa

Understanding RSA Algorithm

RSA 算法是一种公钥加密技术,被认为是最安全的加密方式。它由 Rivest、Shamir 和 Adleman 于 1978 年发明,因此得名 RSA 算法。

RSA algorithm is a public key encryption technique and is considered as the most secure way of encryption. It was invented by Rivest, Shamir and Adleman in year 1978 and hence name RSA algorithm.

Algorithm

RSA 算法具有以下特点:

The RSA algorithm holds the following features −

  1. RSA algorithm is a popular exponentiation in a finite field over integers including prime numbers.

  2. The integers used by this method are sufficiently large making it difficult to solve.

  3. There are two sets of keys in this algorithm: private key and public key.

您必须执行以下步骤才能使用 RSA 算法:

You will have to go through the following steps to work on RSA algorithm −

Step 1: Generate the RSA modulus

初始步骤从选择两个质数 p 和 q 开始,然后计算它们的乘积 N,如下所示:

The initial procedure begins with selection of two prime numbers namely p and q, and then calculating their product N, as shown −

N=p*q

此处,令 N 为指定的大数。

Here, let N be the specified large number.

Step 2: Derived Number (e)

将数字 e 视为一个派生数字,它应该大于 1 且小于 (p-1) 和 (q-1)。主要条件是 (p-1) 和 (q-1) 不存在 1 之外的公因子

Consider number e as a derived number which should be greater than 1 and less than (p-1) and (q-1). The primary condition will be that there should be no common factor of (p-1) and (q-1) except 1

Step 3: Public key

指定的数字对 ne 构成 RSA 公钥,并且公之于众。

The specified pair of numbers n and e forms the RSA public key and it is made public.

Step 4: Private Key

私钥 d 根据数字 p、q 和 e 计算。数字之间的数学关系如下:

Private Key d is calculated from the numbers p, q and e. The mathematical relationship between the numbers is as follows −

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

以上公式是扩展欧几里得算法的基本公式,它把 p 和 q 作为输入参数。

The above formula is the basic formula for Extended Euclidean Algorithm, which takes p and q as the input parameters.

Encryption Formula

考虑一个发送者,他给拥有公钥 (n,e). 的某人发送明文消息。要在给定的场景中加密明文消息,请使用以下语法:

Consider a sender who sends the plain text message to someone whose public key is (n,e). To encrypt the plain text message in the given scenario, use the following syntax −

C = Pe mod n

Decryption Formula

解密过程非常简单,包括分析以便按照系统方式进行计算。假设接收器 C 拥有私钥 d ,则结果模数将被计算为:

The decryption process is very straightforward and includes analytics for calculation in a systematic approach. Considering receiver* C* has the private key d, the result modulus will be calculated as −

Plaintext = Cd mod n

Creating RSA Keys

在本章中,我们将重点介绍使用 Python 逐步实现 RSA 算法。

In this chapter, we will focus on step wise implementation of RSA algorithm using Python.

Generating RSA keys

涉及生成 RSA 密钥的步骤如下:

The following steps are involved in generating RSA keys −

  1. Create two large prime numbers namely p and q. The product of these numbers will be called n, where n= p*q

  2. Generate a random number which is relatively prime with (p-1) and (q-1). Let the number be called as e.

  3. Calculate the modular inverse of e. The calculated inverse will be called as d.

Algorithms for generating RSA keys

我们需要两个主算法才能使用 Python 生成 RSA 密钥—— Cryptomath module * and *Rabin Miller module

We need two primary algorithms for generating RSA keys using Python − Cryptomath module * and *Rabin Miller module.

Cryptomath Module

遵循 RSA 算法的所有基本实现的 Cryptomath 模块的源代码如下:

The source code of cryptomath module which follows all the basic implementation of RSA algorithm is as follows −

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 Module

遵循 RSA 算法的所有基本实现的 RabinMiller 模块的源代码如下:

The source code of RabinMiller module which follows all the basic implementation of RSA algorithm is as follows −

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 密钥的完整代码如下:

The complete code for generating RSA keys is as follows −

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()

Output

公钥和私钥被生成并分别保存在文件中,如下面的输出中所示。

The public key and private keys are generated and saved in the respective files as shown in the following output.

publickey

RSA Cipher Encryption

在本章中,我们将重点介绍 RSA 密码加密的不同实现以及涉及此算法的功能。您可以参考或包含此 Python 文件来实现 RSA 密码算法的实现。

In this chapter, we will focus on different implementation of RSA cipher encryption and the functions involved for the same. You can refer or include this python file for implementing RSA cipher algorithm implementation.

包含在加密算法中的模块如下:

The modules included for the encryption algorithm are as follows −

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。我们将使用一个函数,以使用以下代码生成新密钥或一对公钥和私钥。

We have initialized the hash value as SHA-256 for better security purpose. We will use a function to generate new keys or a pair of public and private key using the following code.

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 算法的以下函数:

For encryption, the following function is used which follows the RSA algorithm −

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

两个参数是必需的: messagepub_key ,它们指公钥。公钥用于加密,而私钥用于解密。

Two parameters are mandatory: message and pub_key which refers to Public key. A public key is used for encryption and private key is used for decryption.

下面提到了加密过程的完整程序:

The complete program for encryption procedure is mentioned below −

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 Cipher Decryption

本章节是上一章节的续篇,在上一章节中我们遵循 RSA 算法逐步实现加密的步骤,并对此进行了详细探讨。

This chapter is a continuation of the previous chapter where we followed step wise implementation of encryption using RSA algorithm and discusses in detail about it.

解密密文所用的函数如下 −

The function used to decrypt cipher text is as follows −

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

对于公钥密码术或非对称密钥密码术来说,保持两个重要特性很重要,即 AuthenticationAuthorization

For public key cryptography or asymmetric key cryptography, it is important to maintain two important features namely Authentication and Authorization.

Authorization

授权是确认发送者是唯一传输信息方的过程。以下代码对此进行了说明 −

Authorization is the process to confirm that the sender is the only one who have transmitted the message. The following code explains this −

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)

Authentication

身份验证可以利用下文说明的验证方法来实现 −

Authentication is possible by verification method which is explained as below −

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)

数字签名将与发送方和接收方的详细信息一起进行验证。这为安全目的增加了更大的分量。

The digital signature is verified along with the details of sender and recipient. This adds more weight age for security purposes.

RSA Cipher Decryption

你可以使用以下代码进行 RSA 解密 −

You can use the following code for RSA cipher decryption −

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)

Hacking RSA Cipher

利用小素数有可能破解 RSA 密码,但如果使用大数,则被认为不可能。如下所述,表明难以破解 RSA 密码的原因包括 −

Hacking RSA cipher is possible with small prime numbers, but it is considered impossible if it is used with large numbers. The reasons which specify why it is difficult to hack RSA cipher are as follows −

  1. Brute force attack would not work as there are too many possible keys to work through. Also, this consumes a lot of time.

  2. Dictionary attack will not work in RSA algorithm as the keys are numeric and does not include any characters in it.

  3. Frequency analysis of the characters is very difficult to follow as a single encrypted block represents various characters.

  4. There are no specific mathematical tricks to hack RSA cipher.

RSA 解密方程为 −

The RSA decryption equation is −

M = C^d mod n

借助小素数,我们可以尝试破解 RSA 密码,其示例代码如下 −

With the help of small prime numbers, we can try hacking RSA cipher and the sample code for the same is mentioned below −

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()

Output

上述代码生成以下输出 -

The above code produces the following output −

hacking rsa cipher