我希望使用Python中的安全散列和加密算法对文件进行加密。在过去使用bcrypt之后,我决定将它用于我的密码计算器,然后通过SHA256传递输出以获取32字节的数据,然后使用它与AES一起加密/解密一个文件:
#!/usr/bin/env python
from argparse import ArgumentParser
from bcrypt import gensalt, hashpw
from Crypto.Cipher import AES
from hashlib import sha256
import os, struct, sys
def main():
parser = ArgumentParser(description = "Encrypts or decrypts a file using " +
"bcrypt for the password and triple AES for file encryption.")
parser.add_argument('-p', '--passphrase', required = True,
help = "The passphrase to use for encryption.")
parser.add_argument('-i', '--input', required = True,
help = "The input file for encryption / decryption.")
parser.add_argument('-o', '--output', required = True,
help = "The output file for encryption / decryption.")
parser.add_argument('-r', '--rounds', default = 10,
help = "The number of bcrypt rounds to use.")
parser.add_argument('-s', '--salt', default = None,
help = "The salt to use with bcrypt in decryption.")
parser.add_argument('operation', choices = ('encrypt', 'decrypt'),
help = "The operation to apply, whether to encrypt or decrypt data.")
parameters = parser.parse_args()
if parameters.operation == 'encrypt':
encrypt(parameters.input, parameters.output, parameters.passphrase,
parameters.rounds)
elif parameters.operation == 'decrypt':
decrypt(parameters.input, parameters.output, parameters.passphrase,
parameters.salt)
def encrypt(input_file, output_file, passphrase, rounds):
bcrypt_salt = gensalt(rounds)
bcrypt_passphrase = hashpw(passphrase, bcrypt_salt)
passphrase_hash = sha256(bcrypt_passphrase).digest()
print "Salt: %s" % (bcrypt_salt, )
iv = os.urandom(16)
cipher = AES.new(passphrase_hash, AES.MODE_CBC, iv)
with open(input_file, 'rb') as infile:
infile.seek(0, 2)
input_size = infile.tell()
infile.seek(0)
with open(output_file, 'wb') as outfile:
outfile.write(struct.pack('<Q', input_size))
outfile.write(iv)
while True:
chunk = infile.read(64 * 1024)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += ' ' * (16 - len(chunk) % 16)
outfile.write(cipher.encrypt(chunk))
return bcrypt_salt
def decrypt(input_file, output_file, passphrase, salt):
print "Salt: %s" % (salt,)
bcrypt_passphrase = hashpw(passphrase, salt)
passphrase_hash = sha256(bcrypt_passphrase).digest()
with open(input_file, 'rb') as infile:
input_size = struct.unpack('<Q', infile.read(struct.calcsize('Q')))[0]
iv = infile.read(16)
cipher = AES.new(passphrase_hash, AES.MODE_CBC, iv)
with open(output_file, 'wb') as outfile:
while True:
chunk = infile.read(64 * 1024)
if len(chunk) == 0:
break
outfile.write(cipher.decrypt(chunk))
outfile.truncate(input_size)
if __name__ == "__main__":
main()
这样的实现有哪些可能的弱点?
我所确定的是,攻击者很容易确定原始文件大小,但这并不能透露文件的多少信息。沙-256不是世界上最好的哈希算法,但是封装一个bcrypt密码会让我相信所有的威胁都会得到缓解。由于bcrypt能够随着时间的推移增加安全性,在算法中添加更多的回合,目前使用bcrypt似乎是一种非常安全的选择。
这个实现有什么漏洞吗?我不是密码专家,但我知道这里使用的三种算法的基础和用途。
发布于 2013-01-22 11:44:43
看了两分钟:
os.urandom()
,就像您所做的)也不坏。https://security.stackexchange.com/questions/29481
复制相似问题