 |
|
 |
In method "TransformFinalBlock" you expect that the inputBuffer is already padded with '\0'.
This is NOT correct in Mono's CryptoStream. It contains the bytes of the last block.
I added a manual zeropadding of the inputBuffer.
[....]
outputBuffer = new byte[16]; // blocksize
uint[] x = new uint[4];
if (inputCount < 16)
{
for (var n = inputCount; n < 16; n++)
{
inputBuffer[n] = 0;
}
}
// load it up
for (int i = 0; i < 4; i++) // should be okay as we have already said to pad with zeros
[...]
Not a very clean way [changing input variables], but it works for me.
|
|
|
|
 |
|
 |
Bearing in mind this article was written in 2002 and Mono was then used as a shortened variation of the word monochrome - I am not surprised.
Thanks for the update
I'll be more enthusiastic about encouraging thinking outside the box when there's evidence of any thinking going on inside it. - pTerryBizSquawk
|
|
|
|
 |
|
 |
The code works fine as such, but there's a little bug in TransformBlock.
This implementation will only transform exactly one block.
It is mitigated by the fact that CanTransformMultipleBlocks is false - but then it should throw when an attempt is made to transform multiple blocks. The comment is also misleading there, as it implies that it would work if set to true. It won't.
|
|
|
|
 |
|
 |
What is the bug?
I'll be more enthusiastic about encouraging thinking outside the box when there's evidence of any thinking going on inside it. - pTerrywww.many-monkeys.com
|
|
|
|
 |
|
 |
I'm sorry, I thought that was clear.
You should throw an ArgumentException in TransformBlock if an attempt is made to transform more than one block, since it does not support it. The current behavior is to transform exactly one block and ignore any that may also be specified in the call. That's a bug.
Also, not a bug, but the comment on CanTransformMultipleBlocks is misleading, when seen with the code. It implies that all one has to do is change the value of canTransformMultipleBlocks to 'true' to get that functionality.
|
|
|
|
 |
|
 |
I see maybe the Property does not work as one would expect but the API is not well documented even after all these years and I made a guess as to what it does; maybe it means that the algorithm can handle all the data and does not need to be repeatably called by the API. Who knows?
The following - keeping the Property untouched (i.e. false) does encrypt the whole array (in this case 64K of data - and can also be decrypted)
Twofish fish = new Twofish();
fish.Mode = CipherMode.CBC;
System.IO.MemoryStream ms = new System.IO.MemoryStream();
//create Twofish Encryptor from this instance
ICryptoTransform encrypt = fish.CreateEncryptor(Key, iv);
//Create Crypto Stream that transforms file stream using twofish encryption
CryptoStream cryptostream = new CryptoStream(ms, encrypt, CryptoStreamMode.Write);
byte[] data = File.ReadAllBytes("Soap Bubbles.bmp");
//write out Twofish encrypted stream
cryptostream.Write(data, 0, data.Length);
cryptostream.Close();
byte[] bytOut = ms.ToArray();
Maybe you have an example of how it doesn't work for you - or on what way is it wrong.
I'll be more enthusiastic about encouraging thinking outside the box when there's evidence of any thinking going on inside it. - pTerrywww.many-monkeys.com
|
|
|
|
 |
|
 |
The following should throw an ArgumentException, or possibly an ArgumentOutOfRangeException:
byte[] sessionKeyBytes = new byte[32];
keyDecryptor.TransformBlock(encryptedSessionKeyK, 0, 32, sessionKeyBytes, 0);
Most implementations of ICryptoTransform will support multiple blocks at once, so it's easy to assume that it does - and when this happens your implementation should throw. Or better yet - support multiple blocks (and then you change the result of CanTransformMultipleBlocks.
|
|
|
|
 |
|
 |
Ahh - I see you are trying to use the code outside the scope provided - If support for multiple blocks is needed I suggest this can be an exercise for the reader. If you need multiple blocks why not use the stream technique as demonstrated?
Since I have no need for using the code in the manner suggested, I have no need to rework it at this moment in time.
In the end this was an investigation into how the API works using Twofish as an example. The comments about multiple blocks was a hangover from another algorithm I implemented for a customer that did support multiple blocks but couldn't use in the example (I checked in my source control - another example of why developers should rework their comments as much as their code - ). So the value of CanTransfromMultipleBlocks is actually correct.
Sorry for the confusion.
I'll be more enthusiastic about encouraging thinking outside the box when there's evidence of any thinking going on inside it. - pTerrywww.many-monkeys.com
|
|
|
|
 |
|
 |
I think we have a difference of viewpoint on writing software. This is a bug. Either you support multiple blocks, or you don't. Either is fine. If you don't, you don't - and then an attempt to use that functionality is an error and must be reported as an error, not silently ignored.
Of course I can live with it as it is, iterate external to your code, fix your code or do any number of things.
I just wanted to give you feed-back on a bug, since one of the points of open source software is that you get such things for free.
There's nothing wrong with having bugs found in your software. All software has bugs, two kinds in fact. Those you know about, and those you don't. What is not so good, is to not fix bugs that are known. But it's entirely up to you, and I meant no criticism.
Thank you for posting your code, I've had use of it, and the core algorithm appears to work as advertised.
|
|
|
|
 |
|
 |
Hi, I like the article you have written. Do you have more documentation for the code?
I have little patience with scientists who take a
board of wood, look for its thinnest part, and drill a
great number of holes where drilling is easy.
-Albert Einstein
|
|
|
|
 |
|
 |
Only what is there - the article is quite old (~4 years)
Do you have any particular questions?
I'll be more enthusiastic about encouraging thinking outside the box when there's evidence of any thinking going on inside it. - pTerrywww.many-monkeys.com
|
|
|
|
 |
|
 |
when I make the source string size less than 16 bytes,
encryption&decryption works fine, but if its size >16 bytes, encrypt it and descryption return the correct string and repeating character.
|
|
|
|
 |
|
 |
Hi
The algorithm is a block cypher (I didn't implement the stream cipher mode) as such it expects data to be a multiple of the block size - if the data is less than that then it pads zeros on the end to make the data up to a full block in size - this is quite normal for a block cipher algorithm.
If the repeating character is a zero then this is normal otherwise please let me know what data you are using so I can repeat the problem and investigate more. It is not uncommon for people to but a leading int in the data to specify how many bytes is in the plaintext if you are using full block sizes.
Technically speaking the dictionary would define Visual Basic users as programmers. But here again, a very generalized, liberal definition is being employed and it's wrong - just plain wrong - Tom Archer 5/12/02
|
|
|
|
 |
|
 |
Hi Shaun,
Since you are padding with zeroes at the end, I would believe this does not conform to PKCS7 padding mode. Can you let me know what change I would need to change it to PKCS7 mode?
Thanks,
Andy
|
|
|
|
 |
|
 |
Sorry I don't know, nor do I have the time to find out at this moment; I'll have to leave that as an exercise for the reader.
I'll be more enthusiastic about encouraging thinking outside the box when there's evidence of any thinking going on inside it. - pTerryBizSquawk
|
|
|
|
 |
|
 |
Hi,
Is Towfish better than rijendal ?
Is it better to do the 2 encryption algo to secure a data ?
Thanks
|
|
|
|
 |
|
 |
They seem to be about even (in fact all the final AES candidates appear to be evenly matched).
I just used Twofish in a legacy home project (since I had previous experience with the blowfish algorithm). MS only included Rijndael into the .NET framework as it was the eventual winner. I wanted to use Twofish again but in the .NET framework (which is similar to the crypto++ architecture), however I could find no documentation so I investigated further and thus this article was born.
> Is it better to do the 2 encryption algo to secure a data ?
If you mean should you encrypt first with one algorithm and then again with another - many experts consider that it is pointless and only wastes CPU cycles.
Technically speaking the dictionary would define Visual Basic users as programmers. But here again, a very generalized, liberal definition is being employed and it's wrong - just plain wrong - Tom Archer 5/12/02
|
|
|
|
 |
|
 |
Thanks for the answer,
I have one more question:
1- If I have an important data and I need it to be secure for 5 years, is AES good choice ?
2- I will encrypt blocks, is it good to encrypt all the block with the same key ?
Bye
|
|
|
|
 |
|
 |
I am not an expert however it should be a good choice - it is supposed to have a high shelf life so it can be used as the US government standard.
learn to understand the various modes such as CBC and EBC - normally you would use CBC as this provides the best security for encrypting repeating data as EBC is good for short data but subjecvt to replay attack.
see www.cryptopp.com[^] for a good encryption reference start
Technically speaking the dictionary would define Visual Basic users as programmers. But here again, a very generalized, liberal definition is being employed and it's wrong - just plain wrong - Tom Archer 5/12/02
|
|
|
|
 |
|
|
 |