【问题标题】:Trouble working with openssl within Python在 Python 中使用 openssl 时遇到问题
【发布时间】:2015-08-13 16:02:44
【问题描述】:

对于初学者,我不能使用任何第 3 方模块,并且我的代码必须与 Python 2.4 一起使用,因为这是一个大型企业环境,并且此工具必须适用于没有第三方模块的 vanilla 2.4 python 安装。

我正在为 openssl 编写一个包装器,用于检索/存储加密数据,主要是用户名/密码和其他身份验证类型的数据。

我正在编写创建模块,它会创建一个新的、空的加密 pickle 文件。

流程如下:

在内存中创建一个腌制对象,它基本上是一个字典对象。 (pickle.dumps) 在内存中加密生成的 pickle 字符串(回显字符串 | openssl .....) 把这个新字符串写成一个泡菜对象。 (pickle.dump)

这是我目前的尝试:

def create(self, wallet, cipher=None, passphrase=None, **kawrgs):

    self.wallet = wallet
    rawdata     = None
    encdata     = None
    outfile     = None

    try:
        outfile = open(self.wallet, 'w')
    except Exception, e:
        raise OpenSSLWalletError("Failed to open '%s' for writing" % self.wallet, None, None, None)

    if passphrase:
        self.passphrase = "-k %s" % passphrase
    else:
        self.passphrase = "-k ''"

    if cipher:
        self.cipher = cipher

    try:
        rawdata = pickle.dumps(self.data)
        cmd = "echo -en '%s' | %s %s -a -salt %s" % (rawdata, self.openssl, self.cipher, self.passphrase)
        os_cmd  = shlex.split(cmd)
        proc = subprocess.Popen(os_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        encdata, stderr = proc.communicate()
        pickle.dump(encdata, outfile)
    except Exception, e:
        raise OpenSSLWalletError("Failed to create encrypted wallet '%s'" % self.wallet, cmd.rstrip(), None, stderr.rstrip())

我相信我的问题与 pickle 在对象中间添加换行符有关,这会破坏 openssl 命令:

这是字符串在 pickle.dumps 之后的样子(基本上这只是一个输入到 pickle 的空字典):

self.data='{}'
'(dp0
.'

如果我在输入到 Popen 之前打印出 cmd,它看起来像这样:

cmd='echo(dp0

。 | /usr/bin/openssl aes-256-cbc -a -salt -k '''

我试过转义字符串,shell=True,shell=False,等等......

有人知道我可以解决这个问题的任何技巧或方法吗?我假设从 pickle 对象中删除换行符会破坏 pickle 格式,并且无法加载,对吗?

感谢您的帮助。

【问题讨论】:

  • 忘记添加“self.data = {}”是在这个类的init方法中定义的。
  • 这对您的情况没有帮助,但看到泡菜是 bleh。我建议不要使用泡菜。因为你必须解开。不能使用任何其他方式

标签: python openssl pickle


【解决方案1】:

由于rawdata 可以包含任意二进制数据,我倾向于非shell 模式,并通过Popen.communicate() 将数据直接传递到openssl 的标准输入中。需要注意的是,您还必须向 Popen 构造函数表明标准输入应该通过管道传输。

rawdata = pickle.dumps(self.data)
cmd = [self.openssl, cipher, "-a", "-salt", "-k", passphrase or "''"]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
encdata, stderr = proc.communicate(input=rawdata)

另请注意,encdata 将以换行符结尾。

【讨论】:

  • 问题是 openssl 不会接受这样的数据。这相当于“openssl
  • 我也总是避免使用 Shell=True,但在这种情况下,我尝试将其作为故障排除工作。
  • 不行,传入proc.communicate()input参数的数据是传给子进程的标准输入的,这也是echo应该实现的。
  • 是的,在 unix 中,“command
  • 哦,对不起,我明白你现在在说什么了。我错过了第一条评论中的 Popen 构造函数中设置stdin=subprocess.PIPE
猜你喜欢
  • 2018-10-14
  • 1970-01-01
  • 1970-01-01
  • 2022-09-23
  • 2020-07-15
  • 2013-06-14
  • 2011-04-13
  • 2017-07-02
  • 1970-01-01
相关资源
最近更新 更多