我正在运行Windows Server 2k8(也许是问题的一半?)无论如何,我从各种语言的不同Blowfish模块中获得了不同的值。有没有一种可以作为标准?
对于以下示例,假定键为password
和明文12345678
。
一个。算法设置为Blowfish
模式且ECB
且已选中Base64 Encode the output
的Online Encrypt Tool给出2mADZkZR0VM=
。无论是明智的选择,我一直以此为参考。
b。以下Perl代码使用Crypt::ECB
和MIME::Base64
use MIME::Base64;
use Crypt::ECB;
$crypt = Crypt::ECB->new;
$crypt->padding(PADDING_NONE);
$crypt->cipher('Blowfish') || die $crypt->errstring;
$crypt->key('password');
$enc = $crypt->encrypt("12345678");
print encode_base64($enc);
这将输出带有PADDING_NONE的
2mADZkZR0VM=
(与上面的“ a。”比较好)。但是,当填充设置为PADDING_AUTO
时,它会输出2mADZkZR0VOZ5o+S6D3OZw==
,至少在我看来,这是一个错误,因为纯文本长8个字符,不需要填充。C。如果我如下使用
Crypt::Blowfish
#! c:\perl\bin
use Crypt::Blowfish;
use MIME::Base64;
my $key;
my $plaintext;
$key = "password";
$plaintext = "12345678";
my $cipher = new Crypt::Blowfish $key;
my $ciphertext = $cipher->encrypt($plaintext);
my $encoded = encode_base64( $ciphertext );
print $encoded;
然后我得到与“ a”匹配的
2mADZkZR0VM=
。以上。这个模块的麻烦之处在于,必须将其分割成8个字节的块才能进行编码。它没有自己的分块器。d。如果使用http://linux.die.net/man/3/bf_ecb_encrypt的源代码(这是我对最近的PHP ext项目所做的工作),则得到的答案与“ a”相同。我倾向于最信任此代码,因为它在SSLeay和OpenSSL中使用。
e。 DI Management的Blowfish: a Visual Basic version中使用
BlowfishEx.EXE
填充的PKCS#5
给出的2mADZkZR0VOZ5o+S6D3OZw==
与使用PADDING_AUTO
的Crypt :: ECB结果相同。将“填充”设置为None
时,我得到与“ a”匹配的2mADZkZR0VM=
。我已经部分回答了我自己写的这个问题:看来我只需要为VB6项目修改DI Management的代码。并可能向Crypt :: ECB的作者提出相同的建议。
但是问题仍然存在:是否有一个值得信赖的河豚参考平台?
最佳答案
您的问题似乎与他们是否正确实现了Blowfish算法有关。在“无填充”变体中,它们似乎都产生相同的结果。
这留下了一个问题,即是否应该完全填充一个8字节的输入。答案很简单:PKCS#7要求输入中至少要填充至少一个字节。原因很简单:在接收端,必须有一种明确的方法来删除填充。对于PKCS#7,填充字节的值始终是接收者需要剥离的填充字节数。
因此,当您收到用PKCS7填充的素材时,请解密该块,然后查看解密输出中的最后一个字节,然后从该块中删除那么多字节。没有结尾的填充块,接收器通常会查看实际数据的最后一个字节,并且该字节碰巧包含的任何值都应剥离那么多字节(尽管它可能会告诉您数字是否为问题大于8)。在任何情况下,为确保正确操作,必须始终至少填充一个字节。在您的情况下,这意味着输入将扩展为16个字节,而不是8个字节。