我必须完成的任务之一需要我从PHP端加密一些东西,然后用Perl解密它。
我发现的PEAR模块似乎适合我的需求是Crypt_CBC。但是,必须有一些我做错或者不理解的事情,因为到目前为止我无法获得正确的结果。
下面的代码摘录专门用于测试目的,因为我想在将它应用到我的实际项目代码之前尝试全部。
首先,这是我的PHP代码,我使用它加密传递给$ text参数的任何内容(即cryptTest.php?text = hello)
require_once('Crypt/CBC.php');
$key = "8326554161EB30EFBC6BF34CC3C832E7CF8135C1999603D4022C031FAEE";
$cipher = new Crypt_CBC($key, 'BLOWFISH');
$encrypted = $cipher->encrypt($text);
if (PEAR::isError($encrypted)) {
echo $encrypted->getMessage();
} else {
echo "ENCRYPTED STRING: " . $encrypted;
}
从那时起,我复制从此脚本回显的任何内容(在我的浏览器输出中)并将其粘贴到我的PERL脚本的$ encrypted变量中:
use Crypt::CBC;
$encrypted = "RandomIVá´bp3Ó¯làK”Á(Û";
my $key = "8326554161EB30EFBC6BF34CC3C832E7CF8135C1999603D4022C031FAEE";
my $vector = "\0\0\0\0\0\0\0\0";
my $cipher = Crypt::CBC->new(
{'key' =>$key,
'cipher' => 'Blowfish',
'iv' => $vector,
'prepend_iv' => 0
});
my $plaintext = $cipher->decrypt($encrypted);
print $plaintext;
我一直在尝试很多东西,比如没有在Perl方面指定IV等等,但它一直给我错误。这个表单是唯一一个我可以获得任何输出的表单。
执行上述结果,原始$ text =“hello”是:Pñšîî7àÐŽZÊ& Rhello
我发现我的原始内容被正确解密,但在我想要的部分之前没有添加一堆垃圾字符。
任何人都可以指出我做错了什么以及如何解决它?
非常感谢。
答案 0 :(得分:5)
我终于找到了解决问题的方法。
感谢你们两位,你们的答案确实有所帮助。我确实按照你的建议在base64中编码/解码,因此避免了任何纯文本编码问题。
为了使解密工作,我必须做的是添加'header'=> 'randomiv'到我的Perl脚本的密码创建,因为PEAR的Crypt_CBC类在加密时使用Random IV。
我在Crypt::CBC's documentation中找到了特定参数。
另外,直接查看CBC.php的解密函数,我发现了它为了确定IV所做的工作:取头部('RandomIV')长度,并将其用作偏移量来加密字符串直到 blocksize 的值(默认为8)。我还指定了 keysize (默认为56)以获得良好的衡量标准。
为了完整性和参考,以下是我更新的测试脚本:
require_once('Crypt/CBC.php');
$key = "8326554161EB30EFBC6BF34CC3C832E7CF8135C1999603D4022C031FAEE";
$cipher = new Crypt_CBC($key, 'BLOWFISH');
$encrypted = $cipher->encrypt($text);
if (PEAR::isError($encrypted)) {
echo $encrypted->getMessage();
} else {
echo "ENCRYPTED STRING: " . base64_encode($encrypted);
}
use Crypt::CBC;
use MIME::Base64;
my $encrypted = decode_base64("UmFuZG9tSVbrNE3ony00FlUbiprLn0fu");
my $key = "8326554161EB30EFBC6BF34CC3C832E7CF8135C1999603D4022C031FAEE";
my $header_spec = "randomiv";
my $blocksize = 8;
my $keysize = 56;
my $iv_offset = length $header_spec;
my $iv = substr $encrypted, $iv_offset, $blocksize;
my $cipher = Crypt::CBC->new(
{'key' =>$key,
'cipher' => 'Blowfish',
'iv' => $iv,
'header' => $header_spec,
'prepend_iv' => $iv_offset,
'blocksize' => $blocksize,
'keysize' => $keysize
})
my $plaintext = $cipher->decrypt($encrypted);
print $plaintext;
你去吧。再次,非常感谢!
马修
答案 1 :(得分:4)
CBC不容错;密文的问题会破坏整个块。因此,您能够使用一些额外的垃圾恢复纯文本这一事实表明问题在于填充,而不是加密本身。
块密码适用于整个块。如果最后一个块不完整,则以允许接收者确定填充内容和数据内容的方式填充。搜索API文档以了解如何处理填充。
如果可能,将解密的明文转换为十六进制并发布,以便可以看到不可打印的字节。这可能会揭示PHP端使用的填充方案。
答案 2 :(得分:3)
您不应该使用加密例程的普通输出执行此操作。您可能会遇到各种编码问题。我建议您对加密后的字符串进行base64编码并复制粘贴,然后在解密前对其进行base64解码。