【问题标题】:How to decrypt Zend2 encrypted data?如何解密 Zend2 加密数据?
【发布时间】:2013-01-24 09:21:14
【问题描述】:

我正在使用Zend2 Crypt module 加密数据。这是我的代码。

$cipher = BlockCipher::factory('mcrypt', array(
  'algorithm' => 'aes',
));
$cipher->setKey('mypassphrase');
$encrypted = $cipher->encrypt('Hey, I am the secret data');

很酷,效果很好!现在,我需要在 Python 中解密 $encrypted 数据(嘿,我是秘密数据)。

我正在使用 pycrypto 来做到这一点。在我的 PHP 环境之外解密数据的步骤是什么?

    from Crypto.Cipher import AES
    import base64
    import hashlib

    password = 'mypassphrase'
    key = hashlib.sha256(password).digest()

    decoded = base64.standard_b64decode(encrypted)
    cipher = AES.new(key, AES.MODE_CBC)
    data = cipher.decrypt(decoded)

我需要指定一个IV,因为 Zend 默认使用 MODE_CBC。如何在我的 Python 代码中指定它?

这是 Zend2 文档:

加密的输出是一个字符串,以 Base64(默认)编码,包含 HMAC 值、IV 向量和加密文本。使用的加密模式是 CBC(默认为随机 IV)和 SHA256 作为 HMAC 的默认哈希算法。默认情况下,Mcrypt 适配器使用 PKCS#7 填充机制进行加密。您可以使用特殊的适配器(Zend\Crypt\Symmetric\Padding)指定不同的填充方法。 BlockCipher 使用的加密和认证密钥是使用 PBKDF2 算法生成的,用作从使用 setKey() 方法指定的用户密钥的密钥派生函数。

有人可以帮助我调整我的 Python 代码来解密数据吗? 谢谢

【问题讨论】:

  • 对不起,只是生成任何使用 mypassphrase 的 AES 代码并不适合我。 PBKDF2 和 HMAC 去哪儿了?

标签: php python zend-framework encryption


【解决方案1】:

我找到了一种方法来解密 Zend2 加密的数据。这是我的代码:

from base64 import b64decode
from Crypto import Random
from Crypto.Cipher import AES
from Crypto.Hash import SHA256, HMAC
from Crypto.Protocol.KDF import PBKDF2

# The hmac starts from 0 to 64 (length).
hmac_size = 64
hmac = data[:hmac_size]

# The cipher text starts after the hmac to the end.
# The cipher text is base64 encoded, so I decoded it.
ciphertext = data[hmac_size:]
ciphertext = b64decode(ciphertext)

# The IV starts from 0 to 16 (length) of the ciphertext.
iv = ciphertext[:16]

# The key size is 256 bits -> 32 bytes.
key_size = 32

# The passphrase of the key.
password = 'mypassphrase'

# The key is generated using PBKDF2 Key Derivation Function.
# In the case of Zend2 Crypt module, the iteration number is 5000, 
# the result length is the key_size * 2 (64) and the HMAC is computed
# using the SHA256 algorithm
the_hash = PBKDF2(password, iv, count=5000, dkLen=64, prf=lambda p, s:
                  HMAC.new(p, s, SHA256).digest())

# The key starts from 0 to key_size (32).
key = the_hash[:key_size]

# The hmac key starts after the key to the end.
key_hmac = the_hash[key_size:]

# HMAC verification
hmac_new = HMAC.new(key_hmac, 'aes%s' % ciphertext, SHA256).hexdigest()
if hmac_new != hmac:
    raise Exception('HMAC verification failed.')

# Instanciate the cipher (AES CBC).
cipher = AES.new(key, AES.MODE_CBC, iv)

# It's time to decrypt the data! The ciphertext starts after the IV (so, 16 after).
data = cipher.decrypt(ciphertext[16:])

任务成功!

【讨论】:

  • 快速问题:我知道这是一个老问题,但是您是如何发现需要在密文中附加一些文本以进行 hmac 验证('aes%s' % ciphertext)的?我查看了 ZF2 文档,但找不到任何对此的参考。谢谢你的帮助。
  • 我目前正在努力解决这个完全相同的问题(除了我在 Java 中解密)。 Zend Crypt 中的 BlockCipher 类表明它在计算哈希时将算法名称附加到密文中。 github.com/zendframework/zend-crypt/blob/…看第438行
猜你喜欢
  • 2011-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-10
  • 1970-01-01
  • 2013-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多