Mật mã với Python - Hướng dẫn nhanh
Mật mã là nghệ thuật giao tiếp giữa hai người dùng thông qua các tin nhắn được mã hóa. Khoa học mật mã xuất hiện với động cơ cơ bản là cung cấp bảo mật cho các thông điệp bí mật được chuyển từ bên này sang bên khác.
Mật mã học được định nghĩa là nghệ thuật và khoa học che giấu thông điệp nhằm giới thiệu sự riêng tư và bí mật được công nhận trong bảo mật thông tin.
Thuật ngữ về mật mã
Các thuật ngữ được sử dụng thường xuyên trong mật mã được giải thích ở đây -
Văn bản thô
Tin nhắn văn bản thuần túy là văn bản có thể đọc được và có thể hiểu được bởi tất cả người dùng. Văn bản thuần túy là thông điệp trải qua quá trình mật mã.
Văn bản mật mã
Văn bản mật mã là thông điệp thu được sau khi áp dụng mật mã trên văn bản thuần túy.
Mã hóa
Quá trình chuyển đổi văn bản thuần túy sang văn bản mật mã được gọi là mã hóa. Nó cũng được gọi là mã hóa.
Giải mã
Quá trình chuyển đổi văn bản mật mã sang văn bản thuần túy được gọi là giải mã. Nó cũng được gọi là giải mã.
Sơ đồ dưới đây cho thấy một minh họa về quá trình hoàn chỉnh của mật mã -
Đặc điểm của mật mã học hiện đại
Các đặc điểm cơ bản của mật mã hiện đại như sau:
Nó hoạt động trên chuỗi bit.
Nó sử dụng các thuật toán toán học để bảo mật thông tin.
Nó yêu cầu các bên quan tâm đến kênh liên lạc an toàn để đạt được sự riêng tư.
Mã hóa cường độ kép, còn được gọi là mã hóa nhiều lần, là quá trình mã hóa một văn bản đã được mã hóa một hoặc nhiều lần, với cùng một thuật toán / mẫu mã hoặc khác nhau.
Các tên khác của mã hóa cường độ kép bao gồm mã hóa tầng hoặc mã hóa tầng.
Các cấp độ mã hóa sức mạnh kép
Mã hóa cường độ gấp đôi bao gồm nhiều cấp độ mã hóa khác nhau được giải thích ở đây trong -
Lớp mã hóa đầu tiên
Văn bản mật mã được tạo từ thông báo có thể đọc được ban đầu bằng cách sử dụng thuật toán băm và khóa đối xứng. Các khóa đối xứng sau này được mã hóa với sự trợ giúp của các khóa không đối xứng. Minh họa tốt nhất cho mẫu này là kết hợp bản phân tích băm của văn bản mật mã vào một viên nang. Người nhận sẽ tính toán thông báo trước và sau đó giải mã văn bản để xác minh rằng văn bản không bị giả mạo ở giữa.
Lớp mã hóa thứ hai
Lớp mã hóa thứ hai là quá trình thêm một lớp nữa vào văn bản mật mã với thuật toán giống hoặc khác nhau. Thông thường, mật khẩu đối xứng dài 32 bit ký tự được sử dụng cho cùng một.
Lớp mã hóa thứ ba
Trong quá trình này, viên nén được mã hóa được truyền qua kết nối SSL / TLS tới đối tác truyền thông.
Sơ đồ sau đây cho thấy một cách tượng hình quá trình mã hóa kép:
Mật mã lai
Mật mã kết hợp là quá trình sử dụng nhiều loại mật mã khác nhau với nhau bằng cách bao gồm các lợi ích của mỗi loại mật mã. Có một cách tiếp cận phổ biến thường được áp dụng là tạo khóa bí mật ngẫu nhiên cho mật mã đối xứng và sau đó mã hóa khóa này thông qua mật mã khóa không đối xứng.
Do mô hình này, bản thân thông điệp gốc được mã hóa bằng cách sử dụng mật mã đối xứng và sau đó sử dụng khóa bí mật. Người nhận sau khi nhận được tin nhắn sẽ giải mã tin nhắn bằng khóa bí mật trước, sử dụng khóa riêng của mình và sau đó sử dụng khóa được chỉ định để giải mã tin nhắn.
Python là một ngôn ngữ kịch bản mã nguồn mở ở mức cao, được thông dịch, tương tác và hướng đối tượng. Nó được thiết kế để dễ đọc. Cú pháp của ngôn ngữ Python dễ hiểu và sử dụng các từ khóa tiếng Anh thường xuyên.
Các tính năng của ngôn ngữ Python
Python cung cấp các tính năng chính sau:
Đã thông dịch
Python được xử lý trong thời gian chạy bằng trình thông dịch. Không cần phải biên dịch một chương trình trước khi thực thi. Nó tương tự như PERL và PHP.
Hướng đối tượng
Python tuân theo kiểu thiết kế và phong cách hướng đối tượng. Nó bao gồm định nghĩa lớp với các tính năng khác nhau như đóng gói và đa hình.
Các điểm chính của ngôn ngữ Python
Các điểm chính của ngôn ngữ lập trình Python như sau:
Nó bao gồm các phương pháp và lập trình chức năng và cấu trúc cũng như các phương pháp lập trình hướng đối tượng.
Nó có thể được sử dụng như một ngôn ngữ kịch bản hoặc một ngôn ngữ lập trình.
Nó bao gồm thu gom rác tự động.
Nó bao gồm các kiểu dữ liệu động cấp cao và hỗ trợ nhiều kiểu kiểm tra động khác nhau.
Python bao gồm một tính năng tích hợp với C, C ++ và các ngôn ngữ như Java.
Liên kết tải xuống ngôn ngữ Python như sau - www.python.org/downloads Nó bao gồm các gói cho các hệ điều hành khác nhau như các bản phân phối Windows, MacOS và Linux.
Chuỗi Python
Khai báo cơ bản của chuỗi được hiển thị bên dưới:
str = 'Hello World!'
Danh sách Python
Danh sách python có thể được khai báo dưới dạng kiểu dữ liệu phức hợp, được phân tách bằng dấu phẩy và được đặt trong dấu ngoặc vuông ([]).
list = [ 'abcd', 786 , 2.23, 'john', 70.2 ]
tinylist = [123, 'john']
Python Tuples
Tuple là kiểu dữ liệu động của Python bao gồm số lượng giá trị được phân tách bằng dấu phẩy. Các bộ giá trị được đặt trong dấu ngoặc đơn.
tinytuple = (123, 'john')
Từ điển Python
Từ điển Python là một loại bảng băm. Khóa từ điển có thể là bất kỳ kiểu dữ liệu nào của Python, thường là số hoặc chuỗi.
tinydict = {'name': 'omkar','code':6734, 'dept': 'sales'}
Gói mật mã
Python bao gồm một gói được gọi là mật mã, cung cấp các công thức và nguyên thủy mật mã. Nó hỗ trợ Python 2.7, Python 3.4+ và PyPy 5.3+. Quá trình cài đặt cơ bản của gói mật mã được thực hiện thông qua lệnh sau:
pip install cryptography
Có nhiều gói khác nhau với cả công thức cấp cao và giao diện cấp thấp cho các thuật toán mật mã phổ biến như symmetric ciphers, message digests và key derivation functions.
Trong suốt hướng dẫn này, chúng tôi sẽ sử dụng các gói Python khác nhau để triển khai các thuật toán mật mã.
Chương trước đã cung cấp cho bạn tổng quan về cài đặt Python trên máy tính cục bộ của bạn. Trong chương này, bạn sẽ tìm hiểu chi tiết về mật mã ngược và cách mã hóa của nó.
Thuật toán mật mã đảo ngược
Thuật toán mật mã ngược có các đặc điểm sau:
Reverse Cipher sử dụng một mẫu đảo ngược chuỗi văn bản thuần túy để chuyển đổi dưới dạng văn bản mật mã.
Quá trình mã hóa và giải mã giống nhau.
Để giải mã văn bản mật mã, người dùng chỉ cần đảo ngược văn bản mật mã để có được văn bản thuần túy.
Hạn chế
Hạn chế chính của mật mã đảo ngược là nó rất yếu. Một hacker có thể dễ dàng phá vỡ văn bản mật mã để lấy được thông điệp gốc. Do đó, mật mã đảo ngược không được coi là lựa chọn tốt để duy trì kênh liên lạc an toàn.
Thí dụ
Hãy xem xét một ví dụ trong đó câu lệnh This is program to explain reverse cipherđược thực hiện với thuật toán mật mã ngược. Đoạn mã python sau sử dụng thuật toán để lấy đầu ra.
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)
Đầu ra
Bạn có thể thấy văn bản đảo ngược, đó là đầu ra như thể hiện trong hình ảnh sau:
Giải trình
Văn bản thuần được lưu trữ trong thông báo biến và biến đã dịch được sử dụng để lưu văn bản mật mã được tạo.
Độ dài của văn bản thuần túy được tính bằng for vòng lặp và với sự trợ giúp của index number. Các ký tự được lưu trữ trong biến văn bản mật mãtranslated được in ở dòng cuối cùng.
Trong chương trước, chúng ta đã đề cập đến mật mã ngược. Chương này nói chi tiết về mật mã Caesar.
Thuật toán mật mã Caesar
Thuật toán của mật mã Caesar có các đặc điểm sau:
Kỹ thuật mật mã Caesar là phương pháp đơn giản và dễ dàng của kỹ thuật mã hóa.
Đây là loại mật mã thay thế đơn giản.
Mỗi chữ cái của văn bản thuần túy được thay thế bằng một chữ cái với một số vị trí cố định xuống bằng bảng chữ cái.
Sơ đồ sau mô tả hoạt động của việc triển khai thuật toán mật mã Caesar -
Chương trình thực hiện thuật toán mật mã Caesar như sau:
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)
Đầu ra
Bạn có thể thấy mật mã Caesar, đó là đầu ra như thể hiện trong hình ảnh sau:
Giải trình
Ký tự văn bản thuần túy được duyệt từng ký tự một.
Đối với mỗi ký tự trong văn bản thuần túy đã cho, hãy biến đổi ký tự đã cho theo quy tắc tùy thuộc vào quy trình mã hóa và giải mã văn bản.
Sau khi các bước được thực hiện, một chuỗi mới được tạo ra được gọi là văn bản mật mã.
Hack thuật toán mật mã Caesar
Văn bản mật mã có thể bị tấn công với nhiều khả năng khác nhau. Một trong những khả năng đó làBrute Force Technique,liên quan đến việc thử mọi khóa giải mã có thể. Kỹ thuật này không đòi hỏi nhiều nỗ lực và tương đối đơn giản đối với một hacker.
Chương trình thực hiện để hack thuật toán mật mã Caesar như sau:
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))
Hãy xem xét văn bản mật mã được mã hóa trong ví dụ trước. Sau đó, kết quả với các phương pháp hack có thể có bằng khóa và sử dụng kỹ thuật tấn công vũ phu như sau:
Cho đến bây giờ, bạn đã học về mật mã đảo ngược và thuật toán mật mã Caesar. Bây giờ, chúng ta hãy thảo luận về thuật toán ROT13 và việc triển khai nó.
Giải thích thuật toán ROT13
Mật mã ROT13 đề cập đến dạng viết tắt Rotate by 13 places. Đó là một trường hợp đặc biệt của Caesar Cipher trong đó sự thay đổi luôn là 13. Mỗi chữ cái được dịch chuyển bởi 13 vị trí để mã hóa hoặc giải mã thông điệp.
Thí dụ
Sơ đồ sau giải thích quy trình thuật toán ROT13 bằng hình ảnh:
Mã chương trình
Chương trình thực hiện thuật toán ROT13 như sau:
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()
Bạn có thể thấy đầu ra ROT13 như trong hình sau:
Hạn chế
Thuật toán ROT13 sử dụng 13 ca. Do đó, rất dễ dàng chuyển các ký tự theo cách ngược lại để giải mã văn bản mật mã.
Phân tích thuật toán ROT13
Thuật toán mật mã ROT13 được coi là trường hợp đặc biệt của Mật mã Caesar. Nó không phải là một thuật toán quá an toàn và có thể bị phá vỡ dễ dàng bằng phân tích tần số hoặc chỉ cần thử 25 khóa có thể có trong khi ROT13 có thể bị phá vỡ bằng cách dịch chuyển 13 vị trí. Do đó, nó không bao gồm bất kỳ mục đích sử dụng thực tế nào.
Mật mã chuyển vị là một thuật toán mật mã trong đó thứ tự của các bảng chữ cái trong bản rõ được sắp xếp lại để tạo thành một văn bản mật mã. Trong quá trình này, các bảng chữ cái văn bản thuần túy thực tế không được bao gồm.
Thí dụ
Một ví dụ đơn giản cho mật mã chuyển vị là columnar transposition ciphertrong đó mỗi ký tự trong văn bản thuần túy được viết theo chiều ngang với chiều rộng bảng chữ cái được chỉ định. Mật mã được viết theo chiều dọc, điều này tạo ra một văn bản mật mã hoàn toàn khác.
Xem xét văn bản thuần túy hello worldvà chúng ta hãy áp dụng kỹ thuật chuyển vị cột đơn giản như hình dưới đây
Các ký tự văn bản thuần túy được đặt theo chiều ngang và văn bản mật mã được tạo với định dạng dọc như : holewdlo lr. Bây giờ, người nhận phải sử dụng cùng một bảng để giải mã văn bản mật mã thành văn bản thuần túy.
Mã
Đoạn mã chương trình sau đây trình bày cách triển khai cơ bản của kỹ thuật chuyển vị cột -
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'))
Giải trình
Sử dụng chức năng split_len(), chúng ta có thể tách các ký tự văn bản thuần túy, có thể được đặt ở định dạng cột hoặc hàng.
encode phương pháp này giúp tạo văn bản mật mã với khóa chỉ định số cột và in văn bản mật mã bằng cách đọc các ký tự qua mỗi cột.
Đầu ra
Mã chương trình để thực hiện cơ bản của kỹ thuật chuyển vị cột cho kết quả sau:
Note- Các nhà phân tích mật mã đã quan sát thấy sự cải thiện đáng kể trong bảo mật tiền điện tử khi kỹ thuật chuyển vị được thực hiện. Họ cũng lưu ý rằng việc mã hóa lại văn bản mật mã bằng cách sử dụng cùng một mật mã chuyển vị tạo ra sự bảo mật tốt hơn.
Trong chương trước, chúng ta đã tìm hiểu về Mật mã chuyển vị. Trong chương này, chúng ta hãy thảo luận về mã hóa của nó.
Pyperclip
Cách sử dụng chính của pyperclipplugin trong ngôn ngữ lập trình Python là thực hiện mô-đun nền tảng chéo để sao chép và dán văn bản vào khay nhớ tạm. Bạn có thể cài đặt pythonpyperclip mô-đun sử dụng lệnh như được hiển thị
pip install pyperclip
Nếu yêu cầu đã tồn tại trong hệ thống, bạn có thể thấy kết quả sau:
Mã
Mã python để mã hóa mật mã chuyển vị trong đó pyperclip là mô-đun chính như được hiển thị bên dưới:
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()
Đầu ra
Mã chương trình để mã hóa mật mã chuyển vị trong đó pyperclip là mô-đun chính cho kết quả sau:
Giải trình
Chức năng main() gọi cho encryptMessage() bao gồm thủ tục tách các ký tự bằng cách sử dụng len chức năng và lặp lại chúng ở định dạng cột.
Chức năng chính được khởi tạo ở cuối để có đầu ra thích hợp.
Trong chương này, bạn sẽ học quy trình giải mã mật mã chuyển vị.
Mã
Hãy quan sát đoạn mã sau để hiểu rõ hơn về việc giải mã mật mã chuyển vị. Văn bản mật mã cho tin nhắnTransposition Cipher với chìa khóa là 6 được tìm nạp như 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()
Giải trình
Văn bản mật mã và khóa được đề cập là hai giá trị được lấy làm tham số đầu vào để giải mã hoặc giải mã văn bản mật mã theo kỹ thuật ngược lại bằng cách đặt các ký tự ở định dạng cột và đọc chúng theo phương ngang.
Bạn có thể đặt các chữ cái ở định dạng cột và sau đó kết hợp hoặc nối chúng với nhau bằng đoạn mã sau:
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)
Đầu ra
Mã chương trình để giải mã mật mã chuyển vị cho kết quả sau:
Trong Python, có thể mã hóa và giải mã các tệp trước khi truyền đến một kênh giao tiếp. Đối với điều này, bạn sẽ phải sử dụng pluginPyCrypto. Bạn có thể cài đặt plugin này bằng lệnh dưới đây.
pip install pycrypto
Mã
Mã chương trình để mã hóa tệp bằng trình bảo vệ mật khẩu được đề cập dưới đây:
# =================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()
Bạn có thể sử dụng lệnh sau để thực hiện quá trình mã hóa cùng với mật khẩu:
python pyfilecipher-encrypt.py -i file_path_for_encryption -o output_path -p password
Đầu ra
Bạn có thể quan sát kết quả sau khi thực thi đoạn mã được đưa ra ở trên:
Giải trình
Mật khẩu được tạo bằng thuật toán băm MD5 và các giá trị được lưu trữ trong các tệp sao lưu an toàn đơn giản trong hệ thống Windows, bao gồm các giá trị như được hiển thị bên dưới -
Trong chương này, chúng ta hãy thảo luận về việc giải mã các tệp trong mật mã bằng Python. Lưu ý rằng đối với quá trình giải mã, chúng ta sẽ làm theo quy trình tương tự, nhưng thay vì chỉ định đường dẫn đầu ra, chúng ta sẽ tập trung vào đường dẫn đầu vào hoặc tệp cần thiết được mã hóa.
Mã
Sau đây là mã mẫu để giải mã tệp bằng mật mã bằng 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()
Bạn có thể sử dụng lệnh sau để thực thi đoạn mã trên:
python pyfilecipher-decrypt.py -i encrypted_file_path -p password
Đầu ra
Bạn có thể quan sát đoạn mã sau khi thực hiện lệnh hiển thị ở trên:
Note - Đầu ra chỉ định các giá trị băm trước khi mã hóa và sau khi giải mã, lưu ý rằng cùng một tệp được mã hóa và quá trình đã thành công.
Mã hóa Base64 chuyển đổi dữ liệu nhị phân thành định dạng văn bản, được chuyển qua kênh giao tiếp nơi người dùng có thể xử lý văn bản một cách an toàn. Base64 còn được gọi làPrivacy enhanced Electronic mail (PEM) và được sử dụng chủ yếu trong quá trình mã hóa email.
Python bao gồm một mô-đun được gọi là BASE64 bao gồm hai chức năng chính như được đưa ra bên dưới:
base64.decode(input, output) - Nó giải mã tham số giá trị đầu vào được chỉ định và lưu trữ đầu ra được giải mã dưới dạng một đối tượng.
Base64.encode(input, output) - Nó mã hóa tham số giá trị đầu vào được chỉ định và lưu trữ đầu ra được giải mã dưới dạng một đối tượng.
Chương trình mã hóa
Bạn có thể sử dụng đoạn mã sau để thực hiện mã hóa base64 -
import base64
encoded_data = base64.b64encode("Encode this text")
print("Encoded text with base 64 is")
print(encoded_data)
Đầu ra
Mã cho mã hóa base64 cung cấp cho bạn kết quả sau:
Chương trình giải mã
Bạn có thể sử dụng đoạn mã sau để thực hiện giải mã base64 -
import base64
decoded_data = base64.b64decode("RW5jb2RlIHRoaXMgdGV4dA==")
print("decoded text is ")
print(decoded_data)
Đầu ra
Mã để giải mã base64 cung cấp cho bạn kết quả sau:
Sự khác biệt giữa ASCII và base64
Bạn có thể quan sát sự khác biệt sau khi làm việc trên ASCII và base64 để mã hóa dữ liệu:
Khi bạn mã hóa văn bản trong ASCII, bạn bắt đầu bằng một chuỗi văn bản và chuyển nó thành một chuỗi byte.
Khi bạn mã hóa dữ liệu trong Base64, bạn bắt đầu với một chuỗi byte và chuyển nó thành chuỗi văn bản.
Hạn chế
Thuật toán Base64 thường được sử dụng để lưu trữ mật khẩu trong cơ sở dữ liệu. Hạn chế chính là mỗi từ được giải mã có thể được mã hóa dễ dàng thông qua bất kỳ công cụ trực tuyến nào và những kẻ xâm nhập có thể dễ dàng lấy được thông tin.
Trong chương này, chúng ta hãy hiểu quy trình XOR cùng với mã hóa của nó bằng Python.
Thuật toán
Thuật toán mã hóa và giải mã XOR chuyển đổi văn bản thuần túy ở định dạng ASCII byte và sử dụng thủ tục XOR để chuyển nó thành một byte xác định. Nó cung cấp những lợi thế sau cho người dùng:
- Tính toán nhanh
- Không có sự khác biệt được đánh dấu ở bên trái và bên phải
- Dễ hiểu và dễ phân tích
Mã
Bạn có thể sử dụng đoạn mã sau để thực hiện quá trình 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)
Đầu ra
Mã cho quy trình XOR cung cấp cho bạn kết quả sau:
Giải trình
Chức năng xor_crypt_string() bao gồm một tham số để chỉ định chế độ mã hóa và giải mã và cả giá trị chuỗi.
Các chức năng cơ bản được thực hiện với các mô-đun base64 tuân theo quy trình / hoạt động XOR để mã hóa hoặc giải mã văn bản thuần túy / văn bản mật mã.
Note - Mã hóa XOR được sử dụng để mã hóa dữ liệu và khó bị bẻ khóa bằng phương pháp brute-force, tức là bằng cách tạo ra các khóa mã hóa ngẫu nhiên để khớp với văn bản mật mã chính xác.
Trong khi sử dụng kỹ thuật mật mã Caesar, việc mã hóa và giải mã các ký hiệu liên quan đến việc chuyển đổi các giá trị thành số với một quy trình cơ bản đơn giản là cộng hoặc trừ.
Nếu phép nhân được sử dụng để chuyển đổi thành văn bản mật mã, nó được gọi là wrap-aroundtình hình. Hãy xem xét các chữ cái và các số liên quan sẽ được sử dụng như hình dưới đây -
Các số sẽ được sử dụng cho quy trình nhân và khóa liên quan là 7. Công thức cơ bản được sử dụng trong trường hợp như vậy để tạo mật mã nhân như sau:
(Alphabet Number * key)mod(total number of alphabets)
Số được tìm nạp thông qua đầu ra được ánh xạ trong bảng được đề cập ở trên và ký tự tương ứng được coi là ký tự được mã hóa.
Chức năng điều chế cơ bản của mật mã nhân trong Python như sau:
def unshift(key, ch):
offset = ord(ch) - ASC_A
return chr(((key[0] * (offset + key[1])) % WIDTH) + ASC_A)
Note- Ưu điểm với mật mã nhân là nó có thể hoạt động với các khóa rất lớn như 8,953,851. Sẽ mất một khoảng thời gian khá dài để một máy tính có thể sử dụng phần lớn chín triệu phím.
Affine Cipher là sự kết hợp của Multiplicative Cipher và Caesar Cipher. Cách triển khai cơ bản của mật mã affine như thể hiện trong hình dưới đây -
Trong chương này, chúng ta sẽ thực hiện mật mã affine bằng cách tạo lớp tương ứng của nó bao gồm hai hàm cơ bản để mã hóa và giải mã.
Mã
Bạn có thể sử dụng mã sau để triển khai mật mã affine -
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')
Đầu ra
Bạn có thể quan sát kết quả sau khi triển khai mật mã affine:
Đầu ra hiển thị tin nhắn được mã hóa cho tin nhắn văn bản thuần túy Affine Cipher và tin nhắn được giải mã cho tin nhắn được gửi dưới dạng đầu vào abcdefg.
Trong chương này, bạn sẽ tìm hiểu về mật mã đơn pha và cách hack nó bằng Python.
Mật mã đơn pha
Mật mã Monoalphabetic sử dụng sự thay thế cố định để mã hóa toàn bộ thông điệp. Mật mã một pha sử dụng từ điển Python với các đối tượng JSON được hiển thị ở đây -
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',
' ': ' ',
}
Với sự trợ giúp của từ điển này, chúng ta có thể mã hóa các ký tự với các ký tự được liên kết dưới dạng giá trị trong đối tượng JSON. Chương trình sau đây tạo ra một chương trình đơn pha như một biểu diễn lớp bao gồm tất cả các chức năng mã hóa và giải mã.
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)
)
Sau đó, tệp này được gọi để thực hiện quá trình mã hóa và giải mã của mật mã Monoalphabetic được đề cập như dưới đây:
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)
Đầu ra
Bạn có thể quan sát kết quả sau khi bạn triển khai mã được đưa ra ở trên:
Do đó, bạn có thể hack một mật mã một pha với cặp giá trị khóa được chỉ định để bẻ khóa văn bản mật mã thành văn bản thuần túy thực tế.
Mật mã thay thế đơn giản là mật mã được sử dụng phổ biến nhất và bao gồm một thuật toán thay thế mọi ký tự văn bản thuần túy cho mọi ký tự văn bản mật mã. Trong quá trình này, các bảng chữ cái bị lộn xộn so với thuật toán mật mã Caesar.
Thí dụ
Các khóa cho một mật mã thay thế đơn giản thường bao gồm 26 chữ cái. Một khóa ví dụ là -
plain alphabet : abcdefghijklmnopqrstuvwxyz
cipher alphabet: phqgiumeaylnofdxjkrcvstzwb
Ví dụ mã hóa bằng cách sử dụng khóa trên là
plaintext : defend the east wall of the castle
ciphertext: giuifg cei iprc tpnn du cei qprcni
Đoạn mã sau đây cho thấy một chương trình để triển khai mật mã thay thế đơn giản:
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()
Đầu ra
Bạn có thể quan sát kết quả sau khi bạn triển khai mã được đưa ra ở trên:
Trong chương này, chúng tôi sẽ tập trung vào kiểm tra mật mã thay thế bằng cách sử dụng các phương pháp khác nhau, giúp tạo ra các chuỗi ngẫu nhiên như được đưa ra bên dưới:
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()
Đầu ra
Bạn có thể quan sát kết quả đầu ra là các chuỗi được tạo ngẫu nhiên giúp tạo ra các tin nhắn văn bản thuần túy ngẫu nhiên, như được hiển thị bên dưới:
Sau khi kiểm tra thành công, chúng ta có thể quan sát thông báo đầu ra Substitution test passed!.
Vì vậy, bạn có thể hack một mật mã thay thế một cách có hệ thống.
Trong chương này, bạn có thể tìm hiểu về cách triển khai đơn giản của mật mã thay thế hiển thị thông điệp được mã hóa và giải mã theo logic được sử dụng trong kỹ thuật mật mã thay thế đơn giản. Đây có thể được coi là một cách tiếp cận thay thế của mã hóa.
Mã
Bạn có thể sử dụng mã sau để thực hiện giải mã bằng cách sử dụng mật mã thay thế đơn giản:
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')
Đầu ra
Đoạn mã trên cung cấp cho bạn kết quả như được hiển thị ở đây -
Trong chương này, bạn sẽ tìm hiểu chi tiết về các mô-đun khác nhau của mật mã trong Python.
Mô-đun mật mã
Nó bao gồm tất cả các công thức nấu ăn và nguyên thủy, đồng thời cung cấp một giao diện mã hóa cấp cao bằng Python. Bạn có thể cài đặt mô-đun mật mã bằng lệnh sau:
pip install cryptography
Mã
Bạn có thể sử dụng mã sau để triển khai mô-đun mật mã -
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)
Đầu ra
Đoạn mã được đưa ra ở trên tạo ra kết quả sau:
Mã được đưa ra ở đây được sử dụng để xác minh mật khẩu và tạo hàm băm của nó. Nó cũng bao gồm logic để xác minh mật khẩu cho mục đích xác thực.
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')
Đầu ra
Scenario 1 - Nếu bạn đã nhập đúng mật khẩu, bạn có thể tìm thấy kết quả sau:
Scenario 2 - Nếu chúng tôi nhập sai mật khẩu, bạn có thể tìm thấy kết quả sau:
Giải trình
Hashlibgói được sử dụng để lưu trữ mật khẩu trong cơ sở dữ liệu. Trong chương trình này,salt được sử dụng để thêm một chuỗi ngẫu nhiên vào chuỗi mật khẩu trước khi thực hiện hàm băm.
Vignere Cipher bao gồm một bước ngoặt với thuật toán Caesar Cipher được sử dụng để mã hóa và giải mã. Vignere Cipher hoạt động tương tự như thuật toán Caesar Cipher chỉ có một điểm khác biệt chính: Caesar Cipher bao gồm thuật toán dịch chuyển một ký tự, trong khi Vignere Cipher bao gồm khóa có nhiều bảng chữ cái thay đổi.
Phương trình toán học
Để mã hóa, phương trình toán học như sau:
$$ E_ {k} \ left (M {_ {i {}}} \ right) = \ left (M_ {i} + K_ {i} \ right) \; \; \; mod \; \; 26 $$
Để giải mã, phương trình toán học như sau:
$$ D_ {k} \ left (C {_ {i {}}} \ right) = \ left (C_ {i} -K_ {i} \ right) \; \; \; mod \; \; 26 $$
Mật mã Vignere sử dụng nhiều hơn một bộ thay thế, và do đó nó còn được gọi là polyalphabetic cipher. Vignere Cipher sẽ sử dụng phím chữ cái thay vì biểu diễn phím số: Chữ A sẽ được sử dụng cho phím 0, chữ B cho phím 1, v.v. Số lượng các chữ cái trước và sau quá trình mã hóa được hiển thị bên dưới -
Sự kết hợp có thể có của số lượng khóa có thể có dựa trên độ dài khóa Vignere được đưa ra như sau, cho kết quả về mức độ an toàn của Thuật toán mật mã Vignere -
Vignere Tableau
Hoạt cảnh được sử dụng cho mật mã Vignere như hình dưới đây -
Trong chương này, chúng ta hãy hiểu cách triển khai mật mã Vignere. Xem xét văn bảnThis is basic implementation of Vignere Cipher được mã hóa và khóa được sử dụng là PIZZA.
Mã
Bạn có thể sử dụng mã sau để triển khai mật mã Vignere trong 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()
Đầu ra
Bạn có thể quan sát kết quả sau khi bạn triển khai mã được đưa ra ở trên:
Các kết hợp có thể có của việc hack mật mã Vignere là không thể. Do đó, nó được coi là một chế độ mã hóa an toàn.
Mật mã pad một lần là một loại mật mã Vignere bao gồm các tính năng sau:
Nó là một mật mã không thể phá vỡ.
Khóa chính xác bằng độ dài của tin nhắn được mã hóa.
Chìa khóa được tạo thành từ các ký hiệu ngẫu nhiên.
Như tên cho thấy, khóa chỉ được sử dụng một lần và không bao giờ được sử dụng lại cho bất kỳ thư nào khác được mã hóa.
Do đó, tin nhắn được mã hóa sẽ dễ bị tấn công đối với một nhà phân tích mật mã. Khóa được sử dụng cho mật mã đệm một lần được gọi làpad, vì nó được in trên các miếng giấy.
Tại sao nó không thể phá vỡ?
Chìa khóa là không thể phá vỡ do các tính năng sau:
Chìa khóa dài như thông điệp đã cho.
Chìa khóa thực sự ngẫu nhiên và đặc biệt được tạo tự động.
Khóa và văn bản thuần túy được tính theo modulo 10/26/2.
Mỗi khóa nên được sử dụng một lần và được hủy bởi cả người gửi và người nhận.
Cần có hai bản sao của chìa khóa: một với người gửi và một với người nhận.
Mã hóa
Để mã hóa một bức thư, người dùng cần viết một khóa bên dưới bản rõ. Chữ cái rõ ràng được đặt trên cùng và chữ cái chính ở bên trái. Mặt cắt đạt được giữa hai chữ cái là văn bản thuần túy. Nó được mô tả trong ví dụ dưới đây -
Giải mã
Để giải mã một ký tự, người dùng lấy ký tự khóa ở bên trái và tìm ký tự văn bản mật mã trong hàng đó. Ký tự văn bản thuần túy được đặt ở đầu cột nơi người dùng có thể tìm thấy ký tự mật mã.
Python bao gồm một mô-đun triển khai hacky cho one-time-padthực hiện mật mã. Tên gói được gọi là One-Time-Pad bao gồm một công cụ mã hóa dòng lệnh sử dụng cơ chế mã hóa tương tự như thuật toán mật mã một lần.
Cài đặt
Bạn có thể sử dụng lệnh sau để cài đặt mô-đun này:
pip install onetimepad
Nếu bạn muốn sử dụng nó từ dòng lệnh, hãy chạy lệnh sau:
onetimepad
Mã
Đoạn mã sau đây giúp tạo mật mã pad một lần -
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)
Đầu ra
Bạn có thể quan sát kết quả sau khi bạn chạy đoạn mã được đưa ra ở trên:
Note - Thông điệp được mã hóa rất dễ bị bẻ khóa nếu độ dài của khóa nhỏ hơn độ dài của thông điệp (văn bản thuần túy).
Trong mọi trường hợp, khóa không nhất thiết phải ngẫu nhiên, điều này làm cho mật mã đệm một lần như một công cụ đáng giá.
Trong chương này, chúng ta hãy thảo luận chi tiết về mật mã đối xứng và bất đối xứng.
Mật mã đối xứng
Trong loại này, quá trình mã hóa và giải mã sử dụng cùng một khóa. Nó còn được gọi làsecret key cryptography. Các tính năng chính của mật mã đối xứng như sau:
- Nó đơn giản hơn và nhanh hơn.
- Hai bên trao đổi chìa khóa một cách an toàn.
Hạn chế
Hạn chế chính của mật mã đối xứng là nếu khóa bị lộ cho kẻ xâm nhập, thông điệp có thể dễ dàng bị thay đổi và đây được coi là một yếu tố rủi ro.
Tiêu chuẩn mã hóa dữ liệu (DES)
Thuật toán khóa đối xứng phổ biến nhất là Tiêu chuẩn mã hóa dữ liệu (DES) và Python bao gồm một gói bao gồm logic đằng sau thuật toán DES.
Cài đặt
Lệnh cài đặt gói DES pyDES trong Python là -
pip install pyDES
Việc triển khai chương trình đơn giản của thuật toán DES như sau:
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
Nó yêu cầu biến padmode tìm nạp tất cả các gói theo cách triển khai thuật toán DES và tuân theo mã hóa và giải mã theo một cách cụ thể.
Đầu ra
Bạn có thể thấy kết quả sau là kết quả của đoạn mã được đưa ra ở trên:
Mật mã không đối xứng
Nó còn được gọi là public key cryptography.Nó hoạt động theo cách ngược lại của mật mã đối xứng. Điều này ngụ ý rằng nó yêu cầu hai khóa: một để mã hóa và khóa khác để giải mã. Khóa công khai được sử dụng để mã hóa và khóa riêng được sử dụng để giải mã.
Hạn chế
- Do độ dài khóa của nó, nó góp phần làm giảm tốc độ mã hóa.
- Quản lý chính là rất quan trọng.
Đoạn mã chương trình sau đây bằng Python minh họa hoạt động của mật mã không đối xứng bằng cách sử dụng thuật toán RSA và cách triển khai của nó:
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))
Đầu ra
Bạn có thể tìm thấy kết quả sau khi thực thi đoạn mã được đưa ra ở trên:
Thuật toán RSA là một kỹ thuật mã hóa khóa công khai và được coi là cách mã hóa an toàn nhất. Nó được phát minh bởi Rivest, Shamir và Adleman vào năm 1978 và do đó có tên làRSA thuật toán.
Thuật toán
Thuật toán RSA có các tính năng sau:
Thuật toán RSA là một phép lũy thừa phổ biến trong một trường hữu hạn trên các số nguyên bao gồm cả số nguyên tố.
Các số nguyên được sử dụng theo phương pháp này đủ lớn nên rất khó giải.
Có hai bộ khóa trong thuật toán này: khóa riêng và khóa công khai.
Bạn sẽ phải thực hiện các bước sau để làm việc với thuật toán RSA -
Bước 1: Tạo mô-đun RSA
Quy trình ban đầu bắt đầu với việc chọn hai số nguyên tố là p và q, sau đó tính tích của chúng N, như được minh họa:
N=p*q
Ở đây, gọi N là số lớn được chỉ định.
Bước 2: Số phát sinh (e)
Coi số e là số dẫn xuất phải lớn hơn 1 và nhỏ hơn (p-1) và (q-1). Điều kiện chính là không được có thừa số chung của (p-1) và (q-1) ngoại trừ 1
Bước 3: Khóa công khai
Cặp số được chỉ định n và e tạo thành khóa công khai RSA và nó được công khai.
Bước 4: Khóa cá nhân
Khóa cá nhân dđược tính từ các số p, q và e. Mối quan hệ toán học giữa các con số như sau:
ed = 1 mod (p-1) (q-1)
Công thức trên là công thức cơ bản cho Thuật toán Euclid mở rộng, lấy p và q làm tham số đầu vào.
Công thức mã hóa
Hãy xem xét một người gửi gửi tin nhắn văn bản thuần túy cho ai đó có khóa công khai (n,e). Để mã hóa tin nhắn văn bản thuần túy trong tình huống đã cho, hãy sử dụng cú pháp sau:
C = Pe mod n
Công thức giải mã
Quá trình giải mã rất đơn giản và bao gồm các phân tích để tính toán theo cách tiếp cận có hệ thống. Đang xem xét người nhận C có khóa riêng d, mô đun kết quả sẽ được tính là -
Plaintext = Cd mod n
Trong chương này, chúng ta sẽ tập trung vào từng bước triển khai thuật toán RSA bằng Python.
Tạo khóa RSA
Các bước sau liên quan đến việc tạo khóa RSA:
Tạo hai số nguyên tố lớn cụ thể là p và q. Tích của những con số này sẽ được gọi làn, Ở đâu n= p*q
Tạo một số ngẫu nhiên tương đối nguyên tố với (p-1) và (q-1). Hãy để số được gọi là e.
Tính nghịch đảo môđun của e. Nghịch đảo được tính toán sẽ được gọi làd.
Các thuật toán tạo khóa RSA
Chúng tôi cần hai thuật toán chính để tạo khóa RSA bằng Python - Cryptomath module và Rabin Miller module.
Mô-đun Cryptomath
Mã nguồn của mô-đun cryptomath tuân theo tất cả các triển khai cơ bản của thuật toán RSA như sau:
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
Mô-đun RabinMiller
Mã nguồn của mô-đun RabinMiller tuân theo tất cả các triển khai cơ bản của thuật toán RSA như sau:
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
Mã hoàn chỉnh để tạo khóa RSA như sau:
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()
Đầu ra
Khóa công khai và khóa riêng tư được tạo và lưu trong các tệp tương ứng như được hiển thị trong đầu ra sau đây.
Trong chương này, chúng tôi sẽ tập trung vào cách triển khai khác nhau của mã hóa mật mã RSA và các chức năng liên quan cho giống nhau. Bạn có thể tham khảo hoặc bao gồm tệp python này để triển khai thực hiện thuật toán mật mã RSA.
Các mô-đun được bao gồm cho thuật toán mã hóa như sau:
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"
Chúng tôi đã khởi tạo giá trị băm là SHA-256 cho mục đích bảo mật tốt hơn. Chúng tôi sẽ sử dụng một hàm để tạo khóa mới hoặc một cặp khóa công khai và khóa riêng tư bằng cách sử dụng mã sau.
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)
Để mã hóa, hàm sau được sử dụng tuân theo thuật toán RSA:
def encrypt(message, pub_key):
cipher = PKCS1_OAEP.new(pub_key)
return cipher.encrypt(message)
Hai tham số là bắt buộc: message và pub_keytrong đó đề cập đến Khóa công khai. Khóa công khai được sử dụng để mã hóa và khóa riêng được sử dụng để giải mã.
Chương trình hoàn chỉnh cho quy trình mã hóa được đề cập dưới đây:
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)
Chương này là phần tiếp theo của chương trước, nơi chúng ta đã theo dõi bước triển khai mã hóa khôn ngoan bằng thuật toán RSA và thảo luận chi tiết về nó.
Hàm được sử dụng để giải mã văn bản mật mã như sau:
def decrypt(ciphertext, priv_key):
cipher = PKCS1_OAEP.new(priv_key)
return cipher.decrypt(ciphertext)
Đối với mật mã khóa công khai hoặc mật mã khóa không đối xứng, điều quan trọng là phải duy trì hai tính năng quan trọng cụ thể là Authentication và Authorization.
Ủy quyền
Ủy quyền là quá trình xác nhận rằng người gửi là người duy nhất đã truyền thông điệp. Đoạn mã sau giải thích điều này:
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)
Xác thực
Có thể xác thực bằng phương pháp xác minh được giải thích như sau:
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)
Chữ ký điện tử được xác minh cùng với các thông tin chi tiết của người gửi và người nhận. Điều này bổ sung thêm tuổi trọng lượng cho các mục đích bảo mật.
Giải mã mật mã RSA
Bạn có thể sử dụng mã sau để giải mã mật mã 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)
Có thể hack mật mã RSA với các số nguyên tố nhỏ, nhưng nó được coi là không thể nếu nó được sử dụng với các số lớn. Các lý do nêu rõ tại sao khó hack mật mã RSA như sau:
Tấn công vũ phu sẽ không hoạt động vì có quá nhiều phím có thể hoạt động. Ngoài ra, điều này tiêu tốn rất nhiều thời gian.
Tấn công từ điển sẽ không hoạt động trong thuật toán RSA vì các khóa là số và không bao gồm bất kỳ ký tự nào trong đó.
Việc phân tích tần số của các ký tự là rất khó theo dõi vì một khối mã hóa duy nhất đại diện cho các ký tự khác nhau.
Không có thủ thuật toán học cụ thể nào để hack mật mã RSA.
Phương trình giải mã RSA là -
M = C^d mod n
Với sự trợ giúp của các số nguyên tố nhỏ, chúng ta có thể thử hack mật mã RSA và mã mẫu cho mã tương tự được đề cập bên dưới:
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()
Đầu ra
Đoạn mã trên tạo ra kết quả sau: