3

这让我很困惑。

当我尝试使用以下输入使用 Blowfish 加密字符串时: key = "some key" input = "input string"

我得到以下结果:

ruby: ["79af8c8ee9220bde"]
php: 79af8c8ee9220bdec2d1c9cfca7b13c6

我将从 php 应用程序接收字符串,所以我需要让这两个同步,但我不明白为什么 php 字符串会更长。我错过了什么?

php代码:

php > require_once 'Crypt/Blowfish.php';
php > $input = "input string";
php > $key = "some key";
php > $crypt = new Crypt_Blowfish($key);
php > echo bin2hex($crypt->encrypt($input));
79af8c8ee9220bdec2d1c9cfca7b13c6

红宝石代码:

irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'crypt/blowfish'
=> true
irb(main):003:0> input = "input string"
=> "input string"
irb(main):004:0> key = "some key"
=> "some key"
irb(main):005:0> blowfish = Crypt::Blowfish.new(key)
=> #<Crypt::Blowfish:0xb74b10c4 @sBoxes=[[3156471959, 1769696695, 1443271708, 181204541, 
...... 1894848609], @key="some key">
irb(main):006:0> blowfish.encrypt_block(input)
=> "y\257\214\216\351\"\v\336"
irb(main):007:0> blowfish.encrypt_block(input).unpack("H*")
=> ["79af8c8ee9220bde"]
4

6 回答 6

4

Hold on, your Ruby output is 8 bytes? Your input is 12 - it's the Ruby code that's in error here.

I haven't used Crypt::Blowfish (and the documentation is scarce) but you may need to pad your input to a multiple of 64 bits, anyway.

于 2011-03-28T22:04:49.787 回答
3

Assuming that Crypt_Blowfish either uses mcrypt or acts just like it, you're encountering a padding issue. In particular, the string is being right-padded with null bytes until it's as long as a multiple of the block size. From the PHP interactive shell:

php > $bf = mcrypt_module_open('blowfish', '', 'ecb', '');
php > $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($bf), MCRYPT_DEV_RANDOM);
php > $key = 'some key';
php > mcrypt_generic_init($bf, $key, $iv);
php > echo mcrypt_enc_get_block_size($td);
8
php > echo bin2hex(mcrypt_generic($bf, 'input string'));
79af8c8ee9220bdec2d1c9cfca7b13c6
php > echo bin2hex(mcrypt_generic($td, "input string\0\0\0\0"));
79af8c8ee9220bdec2d1c9cfca7b13c6

There doesn't seem to be an obvious way to change the padding mode in mcrypt, and I don't know who wrote the library you're using. Check for a padding mode in the module's documentation.

With any luck, you can just set Ruby's padding mode instead, or simply null-pad the string on Ruby's side.

于 2011-03-28T21:33:01.697 回答
1

Since Blowfish is a 64-bit block cipher you'll have to pad the data and the Ruby implementation doesn't do that for you automatically.

s = "input string"
len = s.length
mod = 8-len%8
padded = s.ljust(len+mod, "\0")

I just have to show my first attempt...

encrypted = blowfish.encrypt_block(input. each_char. each_slice(8). map {|slice| slice.count==8 ? slice.join : slice.join.ljust(8,"\0")}.join

I used \0 since that it seems that that is what PHP uses.

于 2011-03-28T21:46:17.290 回答
0

我不知道 Crypt/Blowfish.php 是什么或它是什么 ->encrypt() 方法,但很可能字符串的区别是 php 在调用 crypt() 时使用了盐。

于 2011-03-28T21:30:57.517 回答
0

It looks like the php custom Blowfish script is encrypting incorrectly.

In PHP4 and PHP5, you can use the built in crypt function to encrypt with Blowfish.

PHP crypt().

CRYPT_BLOWFISH - Blowfish hashing with a salt as follows: "$2a$", a two digit cost parameter, "$", and 22 base 64 digits from the alphabet "./0-9A-Za-z". Using characters outside of this range in the salt will cause crypt() to return a zero-length string. The two digit cost parameter is the base-2 logarithm of the iteration count for the underlying Blowfish-based hashing algorithmeter and must be in range 04-31, values outside this range will cause crypt() to fail.

So you can call $hash = crypt($yourString, '$2a$07$'.$aSalt) to encrypt using Blowfish.

If you don't have access to the PHP code, ignore this answer entirely.

于 2011-03-28T21:39:48.790 回答
0

Try blowfish.encrypt_string instead of encrypt_block

于 2012-02-21T06:20:58.557 回答