在 Python 中解密在 PHP 中用 Halite/Libsodium 加密的字符串
Decrypt in Python a string encrypted in PHP with Halite/Libsodium
我使用这个PHP代码来加密一个字符串:
use ParagonIE\Halite\KeyFactory;
use ParagonIE\Halite\Symmetric\Crypto as Symmetric;
use ParagonIE\HiddenString\HiddenString;
define("SECURE_PLACE", '/home/htdocs/secure_place/encryption.key');
/*
//already generated
$enc_key = KeyFactory::generateEncryptionKey();
KeyFactory::save($enc_key, $secure_place);
*/
$enc_key = KeyFactory::loadEncryptionKey(SECURE_PLACE);
$string = "String to be encrypted";
$cipherstring = \ParagonIE\Halite\Symmetric\Crypto::encrypt(
new HiddenString(
$string
),
$enc_key
);
我可以在 PHP 中解密它:
$string = \ParagonIE\Halite\Symmetric\Crypto::decrypt(
$cipherstring,
$enc_key
);
但我需要在 Python3 中完成此操作,因为我要 POST 将加密的字符串发送到 AWS lambda handler.py 函数。
我知道 Halite
是一个 PHP 库,但我也知道它是 Libsodium 的包装器,即 "a portable, cross-compilable, installable, packageable fork of NaCl, with a compatible API, and an extended API to improve usability even further."
有谁知道我应该在 Python3 中使用哪个依赖项(如果可能,请提供代码)来解密字符串?我想我需要将 enc_key
设置为 Lambda 环境变量。
更简单的跨语言秘密
虽然可以尝试找出如何在 Python 中重新创建 Halite 的加密,但我建议在下面移动一层抽象并直接使用 libsodium 的 high level encryption API。
加密数据的PHP代码变为:
$nonce = \Sodium\randombytes_buf(\Sodium\CRYPTO_SECRETBOX_NONCEBYTES);
$string = "String to be encrypted";
$cipherstring = sodium_crypto_secretbox(
$string, $nonce, $enc_key->getRawKeyMaterial());
$encoder = Halite::chooseEncoder(Halite::ENCODE_BASE64URLSAFE);
$cipherstring = $encoder($cipherstring);
$nonce = $encoder($nonce);
现在你只需要将随机数和密码字符串获取到Python,如果你想继续使用base64并使用pynacl包,代码如下所示:
import nacl.secret
import nacl.encoding
decoder = nacl.encoding.URLSafeBase64Encoder
box = nacl.secret.SecretBox(
# Key goes here, doesn't necessarily have to be base64-encoded
"EtUEpKO2q2clEO5HRL0mk-DtQyHIt7Wf_6t1dSacrFI=", decoder
)
nonce = decoder.decode("Maxm2hN-0C4zqE3viwFVJO03I8eWJcm2")
ciphertext = decoder.decode("TpXjfPonHzBQnObD9JPtPhQc-wKIIq8Y-4o_Um3UtVut-ixCDp4=")
print(box.decrypt(ciphertext, nonce))
理由
我之所以这么说,是因为如果你深入研究 Halite 的 encryption code,他们实际上已经手动重新实现了很多 secretbox 的功能。岩盐似乎真的只设计用于 PHP。通过直接使用 libsodium,您可以避免 Halite 更改其协议并破坏您的代码的可能性。
我使用这个PHP代码来加密一个字符串:
use ParagonIE\Halite\KeyFactory;
use ParagonIE\Halite\Symmetric\Crypto as Symmetric;
use ParagonIE\HiddenString\HiddenString;
define("SECURE_PLACE", '/home/htdocs/secure_place/encryption.key');
/*
//already generated
$enc_key = KeyFactory::generateEncryptionKey();
KeyFactory::save($enc_key, $secure_place);
*/
$enc_key = KeyFactory::loadEncryptionKey(SECURE_PLACE);
$string = "String to be encrypted";
$cipherstring = \ParagonIE\Halite\Symmetric\Crypto::encrypt(
new HiddenString(
$string
),
$enc_key
);
我可以在 PHP 中解密它:
$string = \ParagonIE\Halite\Symmetric\Crypto::decrypt(
$cipherstring,
$enc_key
);
但我需要在 Python3 中完成此操作,因为我要 POST 将加密的字符串发送到 AWS lambda handler.py 函数。
我知道 Halite
是一个 PHP 库,但我也知道它是 Libsodium 的包装器,即 "a portable, cross-compilable, installable, packageable fork of NaCl, with a compatible API, and an extended API to improve usability even further."
有谁知道我应该在 Python3 中使用哪个依赖项(如果可能,请提供代码)来解密字符串?我想我需要将 enc_key
设置为 Lambda 环境变量。
更简单的跨语言秘密
虽然可以尝试找出如何在 Python 中重新创建 Halite 的加密,但我建议在下面移动一层抽象并直接使用 libsodium 的 high level encryption API。
加密数据的PHP代码变为:
$nonce = \Sodium\randombytes_buf(\Sodium\CRYPTO_SECRETBOX_NONCEBYTES);
$string = "String to be encrypted";
$cipherstring = sodium_crypto_secretbox(
$string, $nonce, $enc_key->getRawKeyMaterial());
$encoder = Halite::chooseEncoder(Halite::ENCODE_BASE64URLSAFE);
$cipherstring = $encoder($cipherstring);
$nonce = $encoder($nonce);
现在你只需要将随机数和密码字符串获取到Python,如果你想继续使用base64并使用pynacl包,代码如下所示:
import nacl.secret
import nacl.encoding
decoder = nacl.encoding.URLSafeBase64Encoder
box = nacl.secret.SecretBox(
# Key goes here, doesn't necessarily have to be base64-encoded
"EtUEpKO2q2clEO5HRL0mk-DtQyHIt7Wf_6t1dSacrFI=", decoder
)
nonce = decoder.decode("Maxm2hN-0C4zqE3viwFVJO03I8eWJcm2")
ciphertext = decoder.decode("TpXjfPonHzBQnObD9JPtPhQc-wKIIq8Y-4o_Um3UtVut-ixCDp4=")
print(box.decrypt(ciphertext, nonce))
理由
我之所以这么说,是因为如果你深入研究 Halite 的 encryption code,他们实际上已经手动重新实现了很多 secretbox 的功能。岩盐似乎真的只设计用于 PHP。通过直接使用 libsodium,您可以避免 Halite 更改其协议并破坏您的代码的可能性。