Python开发篇——RSA加密算法和SHA1计算文件校验码

做过开发的都会接触到加密算法和hash算法,这两者是有区别的,加密算法分为对称加密和非对称加密,目的是、对数据进行加密/解密,而hash则是单向算法,无法还原原始数据。

RSA加密/解密

目前简单的非对称加密是RSA,还有其他的如椭圆等,各位可以自行研究

  1. 首先需要crypto的lib

    $ pip install pycryptodome
    # or
    $ poetry add pycryptodome

  2. generate_key.py: 生成公钥和密钥

    from Crypto.PublicKey import RSA

    key = RSA.generate(2048)
    private_key = key.export_key()
    file_out = open("private.pem", "wb")
    file_out.write(private_key)
    file_out.close()

    public_key = key.publickey().export_key()
    file_out = open("receiver.pem", "wb")
    file_out.write(public_key)
    file_out.close()

  3. 加密和解密(文件版)

    官方代码:

    from Crypto.PublicKey import RSA
    from Crypto.Random import get_random_bytes
    from Crypto.Cipher import AES, PKCS1_OAEP

    data = "I met aliens in UFO. Here is the map.".encode("utf-8")
    file_out = open("encrypted_data.bin", "wb")

    recipient_key = RSA.import_key(open("receiver.pem").read())
    session_key = get_random_bytes(16)

    Encrypt the session key with the public RSA key

    cipher_rsa = PKCS1_OAEP.new(recipient_key)
    enc_session_key = cipher_rsa.encrypt(session_key)

    Encrypt the data with the AES session key

    cipher_aes = AES.new(session_key, AES.MODE_EAX)
    ciphertext, tag = cipher_aes.encrypt_and_digest(data)
    [ file_out.write(x) for x in (enc_session_key, cipher_aes.nonce, tag, ciphertext) ]
    file_out.close()

  4. 加密和解密(Data版)

    由于pycryptodome的加密都是基于bytes,所以str需要与bytes的转换, 代码如下:

    from Crypto.PublicKey import RSA
    from Crypto.Random import get_random_bytes
    from Crypto.Cipher import PKCS1_OAEP # AES,
    from Crypto.Util.Padding import pad, unpad

    RSA public key

    recipient_key = RSA.import_key(open("receiver.pem").read())
    data = '123456'
    # 通过decode转换bytes,另一种方法是bytes(data, 'utf-8'), 但是存在损耗
    session_key = data.encode('utf-8')
    # Encrypt the session key with the public RSA key
    cipher_rsa = PKCS1_OAEP.new(recipient_key)
    enc_session_key = cipher_rsa.encrypt(pad(session_key, 16))
    # 将bytes转str,用于保存与varchar数据字段
    enc_session_key = enc_session_key.decode('raw_unicode_escape')

    private_key = RSA.import_key(open("private.pem").read())

    Decrypt the session key with the private RSA key

    cipher_rsa = PKCS1_OAEP.new(private_key)
    # 将str转bytes
    session_key = unpad(cipher_rsa.decrypt(enc_session_key.encode('raw_unicode_escape')), 16)
    decrypted = session_key.decode('utf-8')
    user.passwd = decrypted

SHA1计算文件校验码

关于计算文件的校验码,从速度上来说crc32 > sha1 > md5,从安全性角度sha1 > md5 > crc32, 所以在使用中自己取舍, 但是目前许多大厂转向sha256,主要是安全性比sha1更高,但是速度就下降了许多。其选择的原因也是他们的数据已经接近或远远超过ZB了。

  1. 添加

    $ pip install hashlib
    # or
    $ poetry add hashlib

  2. 我这里直接引用我写在Flask下的代码, 值的注意的是Flask的文件是FileStorage类型,不是File-like object,需要stream读取,如果读取后需要再读取记得用stream.seek(0),修改偏移量,否则文件读取size为0

    from flask import request, jsonify
    import hashlib

    BUF_SIZE = 65536

    def post_file():
    file = request.files.get('file')

    计算文件的checksum值

    sha1 = hashlib.sha1()
    checksum = ""
    try:
    # with open(file.filename, 'rb') as f:
    while True:
    data = file.stream.read(BUF_SIZE)
    if not data:
    break
    sha1.update(data)

    获取结果

    checksum=sha1.hexdigest()
    except IOError:
    return jsonify({'message': '演算checksum失败!!!'}), 403

参考:

posted @ 2021-08-19 19:26  DisonTangor  阅读(280)  评论(0)    收藏  举报