Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm learning how to use the BouncyCastle c# cipher library for doing encryption. I'm not looking to send messages so I'm not thinking about security etc. I have written my c# code in Visual Studio.

Here is the problem. I have encrypted the text "Hello World!", using Twofish in CFB mode. The key is 1234567812345678. I've used phpfiddle http://phpfiddle.org/ online tool.

$algo = 'twofish';
$mode = 'cfb';

$cipher = mcrypt_module_open($algo,'',$mode,'');

$key = hex2bin('31323334353637383132333435363738'); //1234567812345678
$iv = hex2bin('00000000000000000000000000000000');

mcrypt_generic_init($cipher, $key, $iv);

$plaintext = utf8_encode('Hello World!');
$encrypted = mcrypt_encrypt($algo, $key, $plaintext, $mode, $iv);
printf("<br>Encrypted text: %s<br><br>",base64_encode($encrypted));

$decrypted = mcrypt_decrypt($algo, $key, $encrypted, $mode, $iv);
printf("<br>Decrypted text: %s (%s)<br><br>",$decrypted,bin2hex($decrypted));

mcrypt_generic_deinit($cipher);
mcrypt_module_close($cipher);

The result is as follows

cfdJ+M6MAzG4WJMb (Base64)

I have then created a c# version to decrypt the same text

// ASCII encoding and Zero padding
encoding = Encoding.ASCII
padding = IBlockCipherPadding.zeroBytePadding

// Set up the engine and cipher types
baseCipher = new TwofishEngine();
blockSize = baseCipher.GetBlockSize();    

modeCipher = new CfbBlockCipher(baseCipher, blockSize);
cipher = padding == null ? new PaddedBufferedBlockCipher(modeCipher) : new PaddedBufferedBlockCipher(modeCipher, padding);

// convert the strings to byte array and create a dummy 000000.. iv 

byte[] iv = new byte[blockSize];    // i.e. 16 bytes of zero
keyBytes = _encoding.GetBytes(key);   //1234567812345678
inputBytes = Convert.FromBase64String(inp);

// initiate the cipher with iv parameters
cipher.Init(true, new ParametersWithIV(new KeyParameter(keyBytes), iv));

// do the decryption
console.write(_encoding.GetString(cipher.DoFinal(inputBytes)) + "
";)

But this gives me garbage out. I get HIl1oVW?rEdIp?

Close (H.l.o.W.r.d.) but every other letter is wrong!

ECB mode works fine so it must be something to do with the initialization vector.

Are there some differences between PHP and c# that I havn't learnt yet?

Where is my c# code incorrect in that case?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
258 views
Welcome To Ask or Share your Answers For Others

1 Answer

OK. So I solved it finally. A basic error in my understanding of cipher block modes. CFB and OFB are Stream Ciphers not Padded Buffered block ciphers.

Therefore the cipher setup should have been

modeCipher = new CfbBlockCipher(baseCipher,8);      // Allways 8 bits for a stream cipher !!
cipher = new StreamBlockCipher(modeCipher);

(The cipher.doFinal was changed too but not shown here)

It now works fine.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...