Encrypting a string with Blowfish in ruby returns a shorter string than the same process in php

橙三吉。 提交于 2019-12-04 12:16:48

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.

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.

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.

I don't know what Crypt/Blowfish.php is or what it's ->encrypt() method does but it's likely the difference in string is php using a salt when calling crypt().

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.

Ross

Try blowfish.encrypt_string instead of encrypt_block

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!