admin管理员组文章数量:1639675
数字化时代下,数据安全对各大公司及个人的重要性不言而喻。作为Python语言使用者, 如何进行数据的加密和解密呢?本文带领大家来了解一下。
目录
- sha256算法
- 标准库知识
- 加密与解密数据
- 主程序
sha256算法
sha256算法是目前应用非常广泛的数据加密算法, 可以简单的理解为:通过一个函数,把任意长度的数据转换为一个长度固定的数据串。
性质
不可逆性:sha256加密是一个单向密码体制,即从明文到密文的不可逆映射,只有加密过程没有解密过程。(本文会使用其他方法使数据可以解密。)
压缩性:任意长度的数据,算出的sha256值长度都是固定的。
抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的sha256值都有很大区别。
抗碰撞性:已知原数据和其sha256值,想找到一个具有相同sha256值的数据(即伪造数据)是非常困难的。
标准库知识
*已经熟悉这些模块的, 请忽略。
hashlib模块
hashlib.sha256(byte)
返回一个sha256加密对象obj
, 用于后续操作。注意参数必须是bytes
类型。obj.hexdigest()
获取sha256加密对象的十六进制sha256值, 返回一个字符串。obj.digest()
获取sha256加密对象的二进制sha256值, 返回一个bytes
类型数据。
zlib模块
zlibpress(data, [level])
压缩一个二进制数据, 返回值为压缩后的数据。
data
: 待压缩的数据,bytes
类型。
level
: 压缩级别, 可选参数, 可以是zlib.Z_BEST_COMPRESSION
,Z_DEFAULT_COMPRESSION
, 或Z_NO_COMPRESSION
。zlib.decompress(data)
解压数据, 与zlibpress
相反。注意如果data
数据有损坏, 那么zlib
会报错。
加密与解密数据
加密部分首先计算密码的sha256
值, 再将数据用zlib
压缩,
然后将压缩数据与密码变换得到的sha256
值进行异或运算, 得到结果。
由于密码经过了变换处理, 在不知道密码的情况下, 找到密码变换得到的sha256
值是非常困难的。另外, 使用zlib
压缩也是为了防止找到密码变换得到的sha256
值, 避免数据被直接破解。
比如,原始文件里有一大段的由"00"字节组成的数据,经过异或之后的数据就直接含有sha256
值,会导致数据被破解。
def encrypt(data,password,compress_level=-1):
data = zlib.compress(data,compress_level) # 先使用zlib压缩
sha256=hashlib.sha256(password.encode("utf-8")).hexdigest() # 获取密码的sha256
head = sha256.encode() + len(data).to_bytes(8,"big") # 文件头
mask = hashlib.sha256((password*2).encode("utf-8")
).hexdigest() # 使用密码的变体(重复2次)的sha256作为掩码
mask_num = int.from_bytes(mask.encode(),"little")
encrypted=b''
for i in range(0,len(data),64): # sha256结果为64字节长
num = int.from_bytes(data[i:i+64],"little") # 截取data的一部分
num_enc = num ^ mask_num # 将data的一部分与掩码进行异或运算
encrypted += num_enc.to_bytes(64,"little")
return head + encrypted[:len(data)]
解密部分首先将密码的sha256
值与已加密数据头部的sha256
值进行比对, 如果不匹配, 就提示错误。
再重新把加密数据和密码变换得到的sha256
值进行异或运算, 还原得到压缩数据。再解压, 得到结果。
def decrypt(encrypted,password):
sha256 = encrypted[:64]
if hashlib.sha256(password.encode("utf-8")).hexdigest().encode()\
!= sha256: # 检验密码是否正确
raise TypeError("Invalid password")
mask = hashlib.sha256((password*2).encode("utf-8")).hexdigest() # 掩码
mask_num = int.from_bytes(mask.encode(),"little")
length = int.from_bytes(encrypted[64:64+8],"big") # (压缩的)数据长度
data = b''
for i in range(64+8,len(encrypted),64):
num_enc = int.from_bytes(encrypted[i:i+64],"little")
num = num_enc ^ mask_num # 与掩码进行异或运算
data += num.to_bytes(64,"little")
return zlib.decompress(data[:length]) # 返回原长度的数据
def test(): # 用于程序测试
seq=b"Hello world!";password="123"
#若不等于则引发AssertionError
assert decrypt(encrypt(seq,password),password)==seq
主程序
主程序部分用于处理文件的加密、解密, 以及程序参数sys.argv
。
FILETYPE=".encrypt"
def __ask_replace(filename):
if not os.path.isfile(filename):return True
result=input("文件 %s已存在,要替换它吗? "%filename)
return result.lower().startswith('y')
def main():
if len(sys.argv)==1:
print("命令行: encryption.py 文件名1 [文件名2] [...]\n未提供文件。")
return
for arg in sys.argv[1:]:
print("处理文件 "+arg)
with open(arg,'rb') as fin:
if arg.lower().endswith(FILETYPE):#解密
newfile = arg[:-len(FILETYPE)]
if not __ask_replace(newfile):continue
password = input("输入密码: ")
data = decrypt(fin.read(),password)
else: #加密
newfile = arg + FILETYPE
if not __ask_replace(newfile):continue
password = input("输入密码: ")
data = encrypt(fin.read(),password)
with open(newfile,"wb") as fout:
fout.write(data)
if __name__=="__main__":main()
还有更好的数据加密、解密方法吗? 欢迎读者在评论区留言。
版权声明:本文标题:Python sha256+zlib库 实现简易文件加密算法 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1729293011a1194411.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论