首页 > 编程语言 >Python黑客编程之数据加解密

Python黑客编程之数据加解密

时间:2023-02-15 17:34:25浏览次数:39  
标签:session AES Python encrypted 加解密 bytes 黑客 key cipher

描述

  • 利用非对称密钥RSA和对称密钥AES算法对传输数据进行加密

分析

  • 发送方本地保存有RSA公钥,发送数据前,利用AES算法对传输数据明文进行加密,利用RSA算法对AES的密钥进行加密
  • 将密钥的密文和数据的密文打包到一块进行传输
  • 接收方本地保存有RSA密钥,接收数据后,对传输密文进行拆分,利用RSA算法对AES密钥进行解密,然后利用AES算法还原数据明文

相关知识

  • 常用编码方法对比
    • arscii: 可见字符与不可见字符,同二进制字节的映射关系
    • unicode: 增加了对中文等语言的支持
    • utf-8: unicode的最常用的实现方式,变长编码,使用1~4个字节表示一个符号,对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8编码和ASCII码是相同的
      • python的encoding函数默认编码是utf-8,常用于转换python的字符串对象和字节流对象
    • gbk: 国标,中文编码是双字节来表示的,英文编码是用ascii来表示,即单字节
    • base64: 用64个可打印字符来表示二进制数据
      • 一般用于在HTTP协议下传输数据,因为HTTP协议是文本传输协议,需要将二进制数据转化为字符数据,但直接转换是不行的,因为网络只能传输可打印字符,base64应运而生
      • 编码与解码的处理对象是byte,故对原数据要先编码,使原本的str类型变成byte,解码后直接输出来的是byte对象,故要解码成str对象

代码

  • 生成RSA公钥和密钥
def generate():
    new_key = RSA.generate(2048)
    private_key = new_key.exportKey()
    public_key = new_key.public_key().exportKey()

    with open('key.pri', 'wb') as f:
        f.write(private_key)

    with open('key.pub', 'wb') as f:
        f.write(public_key)
  • 加密:利用AES加密数据,同时用RSA对AES密钥进行加密,将加密后的部分合并,base64编码后传输
def encrypt(plaintext):
    compressed_text = zlib.compress(plaintext)
    session_key = get_random_bytes(16)

    cipher_aes = AES.new(session_key, AES.MODE_EAX)
    ciphertext, tag = cipher_aes.encrypt_and_digest(compressed_text)
    cipher_rsa, _ = get_rsa_cipher('pub')

    encrypted_session_key = cipher_rsa.encrypt(session_key)
    msg_payload = encrypted_session_key + cipher_aes.nonce + tag + ciphertext
    encrypted = base64.encodebytes(msg_payload)
    return encrypted
  • 解密:base64解码密文,用bytesIO对象拆分出密钥和数据部分,读取本地的RSA密钥,用RSA解密出AES的密钥,再用AES解密出明文数据
def decrypt(encrypted):
    encrypted_bytes = BytesIO(base64.decodebytes(encrypted))
    cipher_rsa, keysize_in_bytes = get_rsa_cipher('pri')

    encrypted_session_key = encrypted_bytes.read(keysize_in_bytes)
    nonce = encrypted_bytes.read(16)
    tag = encrypted_bytes.read(16)
    ciphertext = encrypted_bytes.read()

    session_key = cipher_rsa.decrypt(encrypted_session_key)
    cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
    decrypted = cipher_aes.decrypt_and_verify(ciphertext, tag)

    plaintext = zlib.decompress(decrypted)
    return plaintext

def get_rsa_cipher(keytype):
    with open(f'key.{keytype}') as f:
        key = f.read()
    rsakey = RSA.importKey(key)
    return (PKCS1_OAEP.new(rsakey), rsakey.size_in_bytes())
  • 完整代码
from Cryptodome.Cipher import AES, PKCS1_OAEP
from Cryptodome.PublicKey import RSA
from Cryptodome.Random import get_random_bytes
from io import BytesIO

import base64
import zlib

def generate():
    new_key = RSA.generate(2048)
    private_key = new_key.exportKey()
    public_key = new_key.public_key().exportKey()

    with open('key.pri', 'wb') as f:
        f.write(private_key)

    with open('key.pub', 'wb') as f:
        f.write(public_key)

def get_rsa_cipher(keytype):
    with open(f'key.{keytype}') as f:
        key = f.read()
    rsakey = RSA.importKey(key)
    return (PKCS1_OAEP.new(rsakey), rsakey.size_in_bytes())

def encrypt(plaintext):
    compressed_text = zlib.compress(plaintext)
    session_key = get_random_bytes(16)

    cipher_aes = AES.new(session_key, AES.MODE_EAX)
    ciphertext, tag = cipher_aes.encrypt_and_digest(compressed_text)
    cipher_rsa, _ = get_rsa_cipher('pub')

    encrypted_session_key = cipher_rsa.encrypt(session_key)
    msg_payload = encrypted_session_key + cipher_aes.nonce + tag + ciphertext
    encrypted = base64.encodebytes(msg_payload)
    return encrypted

def decrypt(encrypted):
    encrypted_bytes = BytesIO(base64.decodebytes(encrypted))
    cipher_rsa, keysize_in_bytes = get_rsa_cipher('pri')

    encrypted_session_key = encrypted_bytes.read(keysize_in_bytes)
    nonce = encrypted_bytes.read(16)
    tag = encrypted_bytes.read(16)
    ciphertext = encrypted_bytes.read()

    session_key = cipher_rsa.decrypt(encrypted_session_key)
    cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
    decrypted = cipher_aes.decrypt_and_verify(ciphertext, tag)

    plaintext = zlib.decompress(decrypted)
    return plaintext

if __name__ == "__main__":
    generate()
    plaintext = b"This is a secrete message, right?"
    print(decrypt(encrypt(plaintext)))

测试结果

  • 通过加密解密,还原出原文数据

标签:session,AES,Python,encrypted,加解密,bytes,黑客,key,cipher
From: https://www.cnblogs.com/z5onk0/p/17123803.html

相关文章