首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >终端中的文件加密工具

终端中的文件加密工具
EN

Code Review用户
提问于 2017-08-10 00:14:06
回答 2查看 167关注 0票数 4

我为SimpleCrypt库创建了一个包装器,它允许轻松地加密/解密字符串。

使用该应用程序的方法如下:

代码语言:javascript
复制
//To encrypt
python encryptor.py file_name -e

//To decrypt
python encryptor.py file_name -d

基本上,为了加密,我读取该文件,对其进行加密,并创建一个扩展名为.enc的新文件,这样显然(对我来说)它已经被加密了。

我不是在寻找一个超级安全的应用程序,我在辅导,当我离开我的笔记本时,我不想让学生检查他们未来的考试或诸如此类的东西。因此,这是一个小项目,我自己的乐趣,保护文件不受非IT人员。

我想我已经涵盖了每一种情况(拒绝许可、文件不存在、密码错误等等)。

我认为代码看起来会更好,但我最感兴趣的是是否遗漏了一些我不知道的bug (正如我说的,我尽我所能测试了应用程序),或者我忽略了一些Python基础知识。

encryptor.py

代码语言:javascript
复制
import sys
import os.path
import getpass
import simplecrypt

ReadMode = "r"
WriteMode = "w"
EncryptArg = "-e"
DecryptArg = "-d"
PermissionDenied = 13
FileDoesNotExist = 2


def main():
    if not len(sys.argv) == 3:
        print "Incorrect number of arguments."
        print "Expected file-path encrypt/decrypt"
        exit(1)

    filepath = sys.argv[1]
    encrypt_or_decrypt = sys.argv[2]

    if not (encrypt_or_decrypt == EncryptArg or encrypt_or_decrypt == DecryptArg):
        print "2nd argument provided is invalid, expected -e or -d, received : " + encrypt_or_decrypt
        exit(1)

    requires_encryption = encrypt_or_decrypt == EncryptArg

    try:
        stream = open(filepath, ReadMode)
        file_content = stream.read()
        stream.close()

        if requires_encryption:
            password = getpass.getpass("Password to decrypt : ")
            encrypted_content = simplecrypt.encrypt(password, file_content)

            write_stream = open(filepath + ".enc", WriteMode)
            write_stream.write(encrypted_content)
            write_stream.close()
        else:
            if not filepath[-4:0] == ".enc":
                print "File was not encrypted using this application. Expected .enc format."
                exit(1)

            decrypted_content = None
            try:
                password = getpass.getpass("Password : ")
                decrypted_content = simplecrypt.decrypt(password, file_content)
            except simplecrypt.DecryptionException:
                print "Password is invalid."
                exit(1)

            write_stream = open(filepath[:-4], WriteMode)
            write_stream.write(decrypted_content)
            stream.close()

        os.remove(filepath)

    except IOError, ioError:
        if ioError.errno == PermissionDenied:
            print "You do not have permission to access this file. Consider using sudo"
        elif ioError.errno == FileDoesNotExist:
            print "File does not exist."
        else:
            raise ioError

        exit(1)

if __name__ == '__main__':
    main()
EN

回答 2

Code Review用户

回答已采纳

发布于 2017-08-10 08:55:53

  • 你的论点是静态的,很难补充。让我们说,有时候你不想自己清理干净。添加一个-c标志将是很好的。对于大多数*nix命令行应用程序,您可以使用类似于encryptor -ec path的工具来完成这一任务。因此,我强烈建议使用析解析解析。使用类似于: def make_parser():解析器= argparse.ArgumentParser(prog='encryptor') parser.add_argument(' file _path',type=str,help='Path to file to file,以便加密或解密‘)。parser.add_argument('-c',‘-清理’,action='store_false',help=‘停止程序清理’)group = parser.add_mutually_exclusive_group(required=True) group.add_argument('-d',‘- decrypt’,action='store_true',help=‘指定程序应该在解密模式下运行’)。group.add_argument('-e',‘- encrypt’,action='store_true',help=‘指定程序应该在加密模式下运行’)。返回解析器
  • Python中的常量是UPPER_SNAKE_CASE,因此我建议您将ReadMode等更改为这种格式。目前,我把这个变量读成了一个类。
  • 每个使用Python的人都知道open的参数,open(..., 'r')open(..., READ_MODE)简单得多。当不使用'r'时,变量名只会随着时间的推移变得更糟--抽象到公共常量模块,重命名以更好地指定文件,等等。
  • 请使用with我以前写过一个相当通用的答案为什么你要这么做,不管怎么说,你并没有正确地使用它。相反,您需要使用以下之一:#选项1流= open(filepath,'r') try: content = stream.read()最后: stream.close() #选项2加上open(filepath,'r')作为流: content = stream.read()
  • 我不是exit(1)的粉丝。Python有相当好的错误,虽然它们可能更多地针对开发人员,但它们也可以提供给最终用户。但最糟糕的是,如果以后要调试为什么会出现错误,则必须手动更改程序中的每个exit(1),以获得有用的堆栈跟踪。相反,只需包装您的主,打印错误,然后exit。try: main(),除了异常e: print(str(e))引发SystemExit(1)

总之,我会用这样的方法:

代码语言:javascript
复制
import argparse
import getpass
import simplecrypt


def main(args):
    if args.decrypt and not args.filepath.endswith('.enc'):
        raise ValueError('Expected .enc format file to decrypt.')

    with open(args.filepath, 'r') as stream:
        file_content = stream.read()

    password = getpass.getpass('Password: ')
    if args.encrypt:
        file_path = args.filepath + '.enc'
        content = simplecrypt.encrypt(password, file_content)
    else:
        file_path = args.filepath[:-4]
        content = simplecrypt.decrypt(password, file_content)

    with open(file_path, 'w') as write_stream:
        write_stream.write(content)

    if args.cleanup:
        os.remove(args.filepath)


def make_parser():
    parser = argparse.ArgumentParser(prog='encryptor')
    parser.add_argument('file_path', type=str,
                        help='Path to file to encrypt or decrypt.')
    parser.add_argument('-c', '--cleanup', action='store_false',
                        help='Stop program cleanup.')
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('-d', '--decrypt', action='store_true',
                       help='Specify program should run in decrypt mode.')
    group.add_argument('-e', '--encrypt', action='store_true',
                       help='Specify program should run in encrypt mode.')
    return parser



if __name__ == '__main__':
    args = make_parser().parse_args()

    try:
        main(args)
    except Exception as e:
        print(str(e))
        exit(1)
票数 3
EN

Code Review用户

发布于 2017-08-10 01:38:26

如果您使用析解析解析破解argv,您将享受到一些好处,包括免费获得帮助。

定义read & WRITE_MODE可能有点过头了,因为open(f, 'w')是一个标准成语。无论如何,如果您愿意的话,您有机会让with为您关闭文件。例如:

代码语言:javascript
复制
    with open(filepath + ".enc", "wb") as write_stream:
        write_stream.write(encrypted_content)

您可能需要二元模式:"wb“而不是"w”。

考虑抛出一个异常来代替调用exit(1)

对于filepath[-4:0] == ".enc"执行测试,您可以编写:filepath.endswith(".enc")

这里有一个幻数,对应于len(".enc"):filepath[:-4]。考虑更改强制测试,使其使用regexre.compile(r'^(.+)\.enc$')。然后,在指定文件路径时,可以使用match对象的组(1)。

ioError标识符(或根据PEP8)的io_error是准确的,但可能长一点-- err就足够了。最好使用“as”关键字:

代码语言:javascript
复制
except IOError as err:
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/172517

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档