Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
Mono organizations on
GitHub to continue tracking issues. Bugzilla will remain
available for reference in read-only mode. We will continue to work
on open Bugzilla bugs, copy them to the new locations
as needed for follow-up, and add the new items under Related
Our sincere thanks to everyone who has contributed on this bug
tracker over the years. Thanks also for your understanding as we
make these adjustments and improvements for the future.
Please create a new report on
Developer Community or GitHub with
your current version information, steps to reproduce, and relevant error
messages or log files if you are hitting an issue that looks similar to
this resolved bug and you do not yet see a matching new report.
Interesting, this happens with Mono master (and likely on 2.10 since this affects MonoTouch too) but it was working in Mono 2.6.7.
Do you think it is an easy fix? Because then I can stop looking for an alternative.
This is an encoding issue (unrelated to the crypto code). Try adding a C.WL
after calling GetString, e.g.
string sResult = oEncoding.GetString (bHash);
and the same exception will now occurs inside Console.WriteLine.
You're trying to build a string out of a random stream of bytes and I'm pretty
sure that's not (always) legal Unicode-wise even if, in this case, MS.NET
accept it (which does not mean it's a legal string). c.c. Atsushi as he knows a
lot more on this subject than me.
Back to your original code I don't understand why:
a) you're not passing the string directly to Rfc2898DeriveBytes. The algorithm
is designed to accept strings and produce random bytes from it. Preprocessing
the input string does not give you any more security;
b) (if you pre-process) you're not using the Rfc2898DeriveBytes constructor
that accept a byte (instead of constructing a new string instance). That
would skip the unicode encoding (which only takes extra time, but does not add
any security) and would not hit the bug (if it's a legal string).
If you look for an alternative then I suggest (a) over (b).
I could summarize the issue within one line of code:
This is an issue in UTF8Encoding with EncoderReplacementFallbackBuffer, which is *enabled* in mono 2.10 (the patch was originally from JB, https://github.com/mono/mono/commit/f4aff310cfdee02ccf672c648d9736dd386274df#mcs/class/corlib/System.Text ) and thus it didn't happen in 2.6.*.
I committed fixes in git master (5b18ed7) and mono-2-10 (059a6a6).
Aside from the bug existence, I discourage your usage of this pseudo-cryptic UTF bytes. The Unicode encoder replaces invalid bytes (in UTF8 context) into *empty* string, which means, your input string just becomes shorter (sort of insecure).
I will give your proposal a try. Could somebody please explain what it means that this "fallback buffer" stuff was "enabled" in 2.10?
Encoder fallback feature is explained here: http://msdn.microsoft.com/en-us/library/ms404377.aspx#fallbackstrategy
It's just that the fallback implementation existed earlier but was not used until 2.10.
I see. But that means that this implementaion of the fallback strategy had a bug and that's what you fixed now. Correct?
Yes, exactly :)
Thanks Atsushi! I've cherry-picked this into monotouch (mobile-master) for future releases.
However I urge Rene not to depend on this fix since all invalid strings will be empty, hence they will all share the same password using your current code (and that would be very insecure). Please adopt 'a' (or something similar) for your application and note that 'b' is not better since it will be using an empy byte array, representing the empty sting.
Understood and I will adopt "a".