Here is a message encrypted using BlowfishNET. The key used for encryption is "Abcdefghijklmnopqrstuvwxyz1234567890".
IV is not specified when the call is made to BlowfishNET. I store the encrypted message in a file called "BFSTest_encoded.csv".
mGWcw1XJV3ooXbGvzBuShOA2gwcUnW11NZnHm1Nm
8JQktRSoaAKl369jL8ZLnJNF71I5ctZq8wGGtfov
iLj6PoXZWlzcasgBBUMefjGa0h+L53/VODmqCDaL
6jnZycB5VTngY5gt/9VpYxVW0KB5yR0TJrhHQa02
Vgn1I9ePtmbJfOkALXZPwY0H8MDULkzIYX409iSm
6zgu76UvW81qpJiakFDi9jmIbL4NVWYRlVR1xLRC
HiM8X8q0yCT1ZQO9HJE8vHc/jKdEOi8QGNyAOtdd
ku7Ikg4Pzwpk7g+R/TOCx7Q8xDKbV93sFHu1s3co
pZrpCcNmd8Oy1CFazZ5FweWwsFqfgxMqopMrtaG6
Qc1J7cB3fYpI2RDN6xbAJ8HPZWGdOQsobopv+Czt
GFuzVaVfwz8YXrLEXlbRFfv8Cpt8Q320NAAhwjFj
eEUMyPCpzVZaBske4NDJ++7JomijlS8H8cHmmD6P
Hbopy41W8BF9tsV9nqXgYeiVna98MNTEkyToyP/Z
kBhGYJcutv3s9pG7SydwuKCxCd+Dugusnu8lM10/
5UmGJ7YTGFCJvtfpXR9XoMCQ++eT4/YN9kZlim+2
bkjh01xPnG9r7PChWAVxpUVjOisGlZKrPV6tQRPU
qwQ0die7XienUt5e+jACACGMqXWA4O8P5sg/iT3w
Z2+dDIQiUnxCIATKn74/B8V9PDdtHnr5XOP5KPKK
aYcz/gXt1Q6WkWawUIoLvCkobkm5o7MXeAiJCtet
emfA86bV
When decrypted correctly it should look like this:
blowfishsimple,3030,encrypt,this,then,decrypt,1232,it0
blowfishsimple,3030,encrypt,this,then,decrypt,1232,it1
blowfishsimple,3030,encrypt,this,then,decrypt,1232,it2
blowfishsimple,3030,encrypt,this,then,decrypt,1232,it3
blowfishsimple,3030,encrypt,this,then,decrypt,1232,it4
blowfishsimple,3030,encrypt,this,then,decrypt,1232,it5
blowfishsimple,3030,encrypt,this,then,decrypt,1232,it6
blowfishsimple,3030,encrypt,this,then,decrypt,1232,it7
blowfishsimple,3030,encrypt,this,then,decrypt,1232,it8
blowfishsimple,3030,encrypt,this,then,decrypt,1232,it9
Below is the runnable program with which I am unsuccessfully trying to decrypt the encrypted message above.
#!/usr/bin/perl -w
use strict;
use warnings;
use Crypt::CBC;
use Fcntl ':flock';
use MIME::Base64;
my $encodedFileName = "BFSTest_encoded.csv";
my $decodedFileName = "BFSTest_decoded.csv";
my $decryptedFileName = "BFSTest_decrypted.csv";
my $cCipher = "Blowfish";
my $cKey = q{Abcdefghijklmnopqrstuvwxyz1234567890};
my $cIV = "randomiv";
my $cObject = Crypt::CBC->new({ key => $cKey, cipher => $cCipher });
croak( "Invalid cipher type for encryption" ) unless $cObject;
sub read_bytes {
my ($fh, $to_read) = @_;
my $buf = '';
while ($to_read) {
my $bytes_read = read($fh, $buf, $to_read, length($buf));
die("$!\n") if !defined($bytes_read);
die("Unexpected end of file\n") if !$bytes_read;
$to_read -= $bytes_read;
}
return $buf;
}
sub decryptNETData {
my ( $length, $buffer );
print "Now DECRYPTING $decodedFileName for current client ... \n";
open( my $fhREADFROM, "<", $decodedFileName ) || die("Cannot open
+encrypted file $decodedFileName");
binmode $fhREADFROM;
flock $fhREADFROM, LOCK_SH;
open( finalFile, ">", $decryptedFileName ) || die("Cannot open fil
+e $decryptedFileName to write decrypted contents");
binmode finalFile;
flock finalFile, LOCK_EX;
# Tried to slurp, decrypt and decode here, but that did not work e
+ither.
my $decodedFile = do { local( $/ ) ; <$fhREADFROM> } ;
utf8::decode( my $str = $cObject->decrypt( $decodedFile ) );
print finalFile $str;
#while (!eof($fhREADFROM)) {
# $length = unpack('N', read_bytes($fhREADFROM, 4));
# $buffer = read_bytes($fhREADFROM, $length);
# print finalFile $cObject->decrypt( $buffer );
#}
close $fhREADFROM;
close finalFile;
print "Decrypted $decodedFileName to $decryptedFileName. \n";
}
sub decodeData {
open(my $fhENCODEDFILE, "<", $encodedFileName) || die("Cannot open
+ file $encodedFileName");
binmode $fhENCODEDFILE;
flock $fhENCODEDFILE, LOCK_EX;
open(my $fhDECODEDFILE, ">", $decodedFileName) || die("Cannot open
+ file $decodedFileName");
binmode $fhDECODEDFILE;
flock $fhDECODEDFILE, LOCK_EX;
my $utf8base64EncodedFile = do { local( $/ ) ; <$fhENCODEDFILE> }
+;
#utf8::decode( my $str = decode_base64($utf8base64EncodedFile) );
print $fhDECODEDFILE decode_base64($utf8base64EncodedFile);
close $fhENCODEDFILE;
close $fhDECODEDFILE;
print "Decoded $encodedFileName to $decodedFileName. \n";
}
decodeData();
decryptNETData();
Also, I am copying below the encrypt subroutine from the BlowfishSimple class. I apologize if this is of no use.
I don't understand how it is padding the data. I assume encryption is performed in the following order:
- UTF-8 encoded
- Padded to next 8-byte block border (I am unsure about this) and Encrypted
- BASE64 encoded
We have taken your input and are encrypting the entire file as once.
Therefore, the input to the BlowfishSimple class would be the entire file that needs to be encrypted.
public String Encrypt(String plainText)
{
int i, origLen, len, mod;
byte[] ueData, inBuf, outBuf, iv;
ueData = Encoding.UTF8.GetBytes(plainText);
origLen = ueData.Length;
len = origLen;
mod = len % BlowfishCBC.BLOCK_SIZE;
len = (len - mod) + BlowfishCBC.BLOCK_SIZE;
inBuf = new byte[len];
Array.Copy(ueData, 0, inBuf, 0, origLen);
i = len - (BlowfishCBC.BLOCK_SIZE - mod);
while (i < len)
{
inBuf[i++] = (byte)mod;
}
outBuf = new byte[inBuf.Length + BlowfishCBC.BLOCK_SIZE];
iv = new byte[BlowfishCBC.BLOCK_SIZE];
this.rng.GetBytes(iv);
this.bfc.IV = iv;
this.bfc.Encrypt(
inBuf,
0,
outBuf,
BlowfishCBC.BLOCK_SIZE,
inBuf.Length);
Array.Copy(iv, 0, outBuf, 0, BlowfishCBC.BLOCK_SIZE);
String sResult = Convert.ToBase64String(outBuf);
Array.Clear(inBuf, 0, inBuf.Length);
return sResult;
}
Thank you for your help.
| [reply] [d/l] [select] |
Please put <c>...</c> around your long data line! (And please include a newline within those tags.)
The data size doesn't jive.
The cipher text, once base64 decoded, is 576 ( 72*8 ) bytes long.
Your plain text is 550 ( 68*8+6 ) bytes long.
Your padded plain text is 552 ( 69*8 ) bytes long.
The IV is 8 bytes long.
There are 16 ( 576-(552+8) ) unaccounted bytes
Unless the CRLF is used for line endings.
The cipher text, once base64 decoded, is 576 ( 72*8 ) bytes long.
Your plain text is 560 ( 70*8+0 ) bytes long.
Your padded plain text is 568 ( 71*8 ) bytes long.
The IV is 8 bytes long.
There are 0 ( 576-(568+8) ) unaccounted bytes
At least your Java code outputs as many bytes as expected.
The following should produce the plain text.
use strict;
use warnings;
use Crypt::CBC qw( );
use List::MoreUtils qw( apply );
use MIME::Base64 qw( decode_base64 );
my $key = 'Abcdefghijklmnopqrstuvwxyz1234567890';
my $ctext = decode_base64(apply { s/\s//g } <<'__EOI__');
mGWcw1XJV3ooXbGvzBuShOA2gwcUnW11NZnHm1Nm
8JQktRSoaAKl369jL8ZLnJNF71I5ctZq8wGGtfov
iLj6PoXZWlzcasgBBUMefjGa0h+L53/VODmqCDaL
6jnZycB5VTngY5gt/9VpYxVW0KB5yR0TJrhHQa02
Vgn1I9ePtmbJfOkALXZPwY0H8MDULkzIYX409iSm
6zgu76UvW81qpJiakFDi9jmIbL4NVWYRlVR1xLRC
HiM8X8q0yCT1ZQO9HJE8vHc/jKdEOi8QGNyAOtdd
ku7Ikg4Pzwpk7g+R/TOCx7Q8xDKbV93sFHu1s3co
pZrpCcNmd8Oy1CFazZ5FweWwsFqfgxMqopMrtaG6
Qc1J7cB3fYpI2RDN6xbAJ8HPZWGdOQsobopv+Czt
GFuzVaVfwz8YXrLEXlbRFfv8Cpt8Q320NAAhwjFj
eEUMyPCpzVZaBske4NDJ++7JomijlS8H8cHmmD6P
Hbopy41W8BF9tsV9nqXgYeiVna98MNTEkyToyP/Z
kBhGYJcutv3s9pG7SydwuKCxCd+Dugusnu8lM10/
5UmGJ7YTGFCJvtfpXR9XoMCQ++eT4/YN9kZlim+2
bkjh01xPnG9r7PChWAVxpUVjOisGlZKrPV6tQRPU
qwQ0die7XienUt5e+jACACGMqXWA4O8P5sg/iT3w
Z2+dDIQiUnxCIATKn74/B8V9PDdtHnr5XOP5KPKK
aYcz/gXt1Q6WkWawUIoLvCkobkm5o7MXeAiJCtet
emfA86bV
__EOI__
my $blksz = 8; # Chicken-egg UI problem with Crypt::CBC.
my $iv = substr($ctext, 0, $blksz, '');
my $cipher = Crypt::CBC->new(
-cipher => 'Blowfish',
-key => $key,
-header => 'none',
-iv => $iv,
);
binmode(STDOUT);
print($cipher->decrypt($ctext));
...But it doesn't. I'll have to study how the key is used by both libraries. Or maybe it's some byte ordering problem? But I don't think so from what I've seen.
Your padding method could be problematic. You use
byte fill = (byte)mod; while (i < len) { inBuf[i++] = (byte)fill; }
but Crypt::CBC expects
byte fill = (byte)(len-origLen); while (i < len) { inBuf[i++] = (byte)fill; }
| [reply] [d/l] [select] |