做过开发的都会接触到加密算法和hash算法,这两者是有区别的,加密算法分为对称加密和非对称加密,目的是、对数据进行加密/解密,而hash则是单向算法,无法还原原始数据。
RSA加密/解密
目前简单的非对称加密是RSA,还有其他的如椭圆等,各位可以自行研究
-
首先需要crypto的lib
$ pip install pycryptodome # or $ poetry add pycryptodome
-
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()
-
加密和解密(文件版)
官方代码:
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()
-
加密和解密(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
了。
-
添加
$ pip install hashlib # or $ poetry add hashlib
-
我这里直接引用我写在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
参考: