如何使用PyCrypto解密使用OpenSSL加密的内容? [英] How can I decrypt something with PyCrypto that was encrypted using OpenSSL?

查看:113
本文介绍了如何使用PyCrypto解密使用OpenSSL加密的内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个使用OpenSSL加密的字符串.例如:

I have several strings that were encrypted using OpenSSL. For instance:

$ echo "original string" | openssl aes-256-cbc -p -a -pass pass:secret
salt=B898FE40EC8155FD
key=4899E518743EB0584B0811AE559ED8AD9F0B5FA31B0B998FEB8453B8E3A7B36C
iv =EFA6105F30F6C462B3D135725A6E1618
U2FsdGVkX1+4mP5A7IFV/VcgRs4ci/yupMErHjf5bkT5XrcowXK7z3VyyV1l2jvy

我想用Python解密这些东西.我正在尝试使用PyCrypto.这是一个使用上述数据的示例脚本:

I would like to decrypt these things using Python. I'm attempting to use PyCrypto. Here's an exmaple script using the above data:

from base64 import b64decode, b64encode
from hashlib import md5
from Crypto.Cipher import AES

secret = 'secret'
encoded = 'U2FsdGVkX1+4mP5A7IFV/VcgRs4ci/yupMErHjf5bkT5XrcowXK7z3VyyV1l2jvy'
encrypted = b64decode(encoded)
salt = encrypted[8:16]
data = encrypted[16:]
key = md5(secret + salt).hexdigest()
iv = md5(key + secret + salt).hexdigest()[0:16] # which 16 bytes?
dec = AES.new(key, AES.MODE_CBC, iv)
clear = dec.decrypt(data)

try:
    salt_hex = ''.join(["%X" % ord(c) for c in salt])
    print 'salt:     %s' % salt_hex
    print 'expected: %s' % 'B898FE40EC8155FD'
    print 'key:      %s' % key.upper()
    print 'expected: %s' % '4899E518743EB0584B0811AE559ED8AD9F0B5FA31B0B998FEB8453B8E3A7B36C'
    print 'iv:       %s' % iv
    print 'expected: %s' % 'EFA6105F30F6C462B3D135725A6E1618'
    print 'result: %s' % clear
except UnicodeDecodeError:
    print 'decryption failed'

这是输出:

salt:     B898FE40EC8155FD
expected: B898FE40EC8155FD
key:      4899E518743EB0584B0811AE559ED8AD
expected: 4899E518743EB0584B0811AE559ED8AD9F0B5FA31B0B998FEB8453B8E3A7B36C
iv:       17988376b72f4a81
expected: EFA6105F30F6C462B3D135725A6E1618
decryption failed

您可以看到盐匹配,并且密钥与OpenSSL显示的前半部分匹配,因此我似乎处于正确的轨道上,但是有两个主要问题:

You can see that the salt matches, and the key matches the first half of what OpenSSL shows, so I seem to be on the right track, but there are two main questions:

  1. 为什么OpenSSL中的keyiv的值是PyCrypto(可能是AES256)允许的两倍?
  2. 如何生成正确的值?我使用的技术来自博客,但是如果IV总是与块大小(16字节)匹配,则MD5将永远无法工作.即使我能弄清楚密钥的另一半来自何处,PyCrypto也会因为它太长而拒绝它.
  1. Why are the values for key and iv from OpenSSL twice as long as PyCrypto (and presumably AES256) allows?
  2. How do I generate the correct values? The technique I'm using was taken from a blog, but if the IV is always supposed to match the block size (16 bytes), MD5 will never work. And even if I could figure out where the other half of the key comes from, PyCrypto would refuse it for being too long.

我意识到我也需要删除填充,但是为了简洁起见,我省略了它.

I realize I'll need to remove the padding as well, but I left that out for brevity.

推荐答案

您遇到三个问题:

  1. 您在OpenSSL中使用AES256(32字节密钥),而在python代码中使用AES128(16字节密钥).
  2. IV计算错误. OpenSSL的密钥派生功能中的每个步骤都使用最后计算出的MD5摘要.
  3. 您混合使用二进制和十六进制表示形式.在可视化之前,最后将任何转换都转换为十六进制.

以下代码应正确:

from base64 import b64decode, b64encode
from binascii import hexlify
from Crypto.Cipher import AES
from Crypto.Hash import MD5

secret = 'secret'
encoded = 'U2FsdGVkX1+4mP5A7IFV/VcgRs4ci/yupMErHjf5bkT5XrcowXK7z3VyyV1l2jvy'
encrypted = b64decode(encoded)
salt = encrypted[8:16]
data = encrypted[16:]

# We need 32 bytes for the AES key, and 16 bytes for the IV
def openssl_kdf(req):
    prev = ''
    while req>0:
        prev = MD5.new(prev+secret+salt).digest()
        req -= 16
        yield prev
mat = ''.join([ x for x in openssl_kdf(32+16) ])
key = mat[0:32]
iv  = mat[32:48]

dec = AES.new(key, AES.MODE_CBC, iv)
clear = dec.decrypt(data)

try:
    salt_hex = ''.join(["%X" % ord(c) for c in salt])
    print 'salt:     %s' % salt_hex
    print 'expected: %s' % 'B898FE40EC8155FD'
    print 'key:      %s' % hexlify(key).upper()
    print 'expected: %s' % '4899E518743EB0584B0811AE559ED8AD9F0B5FA31B0B998FEB8453B8E3A7B36C'
    print 'iv:       %s' % hexlify(iv).upper()
    print 'expected: %s' % 'EFA6105F30F6C462B3D135725A6E1618'
    print 'result:   %s' % clear
except UnicodeDecodeError:
    print 'decryption failed'

这篇关于如何使用PyCrypto解密使用OpenSSL加密的内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆