哪种 Blowfish 算法最“正确”?
我正在运行 Windows Server 2k8(也许这只是问题的一半?)无论如何,我从不同语言的不同 Blowfish 模块中获取不同的值。有没有一个可以信赖的标准呢?
对于以下示例,假设密钥为 password
和明文 12345678
。
一个。 在线加密工具,算法设置为 Blowfish
模式 ECB
和 Base64 编码输出
检查后给出 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 字节块才能进行编码;它没有自己的分块器。
e. DI Management 的 Blowfish:Visual Basic 中的 BlowfishEx.EXE
具有 PKCS#5
填充的版本 给出 2mADZkZR0VOZ5o+S6D3OZw==
,这与具有 PADDING_AUTO
的 Crypt::ECB 结果相同。将 Padding 设置为 None
后,我得到与“a”匹配的 2mADZkZR0VM=
。
我写这篇文章已经部分回答了我自己的问题:看起来我只需要修改 VB6 项目的 DI Management 代码。也许也可以向 Crypt::ECB 的作者提出同样的建议。
但问题仍然存在:是否有值得信赖的河豚参考平台?
I'm running Windows Server 2k8 (maybe that's half the problem?) Anyway, I'm getting different values out of different Blowfish modules in various languages. Is there one which can be relied upon as the standard?
For the following examples, assume the key is password
and the plaintext 12345678
.
a. The Online Encrypt Tool with Algorithm set to Blowfish
mode ECB
and Base64 Encode the output
checked gives 2mADZkZR0VM=
. I've been using this a my reference point, wise or otherwise.
b. The following Perl code uses Crypt::ECB
and 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);
This outputs 2mADZkZR0VM=
with PADDING_NONE (which compares well with 'a.' above). However, when padding is set to PADDING_AUTO
it outputs 2mADZkZR0VOZ5o+S6D3OZw==
which is, in my mind at least, a bug as the plaintext is 8 characters long and in no need of padding.
c. If I use Crypt::Blowfish
as below
#! 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;
then I get 2mADZkZR0VM=
which matches 'a.' above. Trouble with this module though is that one has to segment things into 8 byte chunks for encoding; it has no chunker of its own.
d. If I use the source at http://linux.die.net/man/3/bf_ecb_encrypt (which I did for a recent PHP ext project) then I get the same answer as 'a.'. I'm inclined to trust this code the most as it's in use in SSLeay and OpenSSL.
e. The BlowfishEx.EXE
in DI Management's Blowfish: a Visual Basic version with PKCS#5
padding gives 2mADZkZR0VOZ5o+S6D3OZw==
which is the same as the Crypt::ECB results with PADDING_AUTO
. With Padding set to None
I get 2mADZkZR0VM=
which matches 'a.'
I've partly answered my own question writing this: looks like I just have to modify DI Management's code for the VB6 project. And maybe suggest the same to the writer of Crypt::ECB.
But the question remains: is there a trustworthy blowfish reference platform?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的问题似乎不在于他们是否正确实现了 Blowfish 算法。在“无填充”变体中,它们似乎都产生相同的结果。
这就留下了一个问题:是否应该填充 8 字节输入。答案非常简单:PKCS #7 要求输入中始终添加至少一个字节的填充。原因很简单:在接收端,需要有一种明确的方法来删除填充。在 PKCS#7 的情况下,填充字节的值始终是接收方需要剥离的填充字节数。
因此,当您收到用 PKCS7 填充的材料时,您可以解密该块,然后查看解密输出中的最后一个字节,并从该块中删除那么多字节。如果末尾没有填充块,接收器通常会查看实际数据的最后一个字节,无论该字节恰好包含什么值,都会去掉那么多字节(尽管它可能会告诉您如果数字是有问题的)大于8)。无论如何,为了确保正确操作,必须始终有至少一个字节的填充。在您的情况下,这意味着输入扩展为 16 个字节而不是 8 个字节。
Your problem doesn't seem to be with whether they implement the Blowfish algorithm correctly. In the "no padding" variant, they all seem to produce identical results.
That leaves a question of whether an 8-byte input should be padded at all. The answer to this is pretty simple: PKCS #7 requires that there is always at least one byte of padding added to the input. The reason for this is simple: on the receiving end, there needs to be an unambiguous way to remove the padding. In the case of PKCS#7, the value of the padding bytes is always the number of bytes of padding that needs to be stripped off by the recipient.
So, when you receive material that's been padded with PKCS7, you decrypt the block, then look at the last byte in the decrypted output, and remove that many bytes from the block. Without a block of padding on the end, the receiver would normally look at the last byte of actual data, and whatever value that byte happened to contain, strip off that many bytes (though it should probably tell you there's a problem if the number is larger than 8). In any case, to assure correct operation, there must always be at least one byte of padding. In your case, that means the input gets expanded out to 16 bytes instead of 8.