Which public-domain encryption libraries would you prefer to use with .NET?
I found http://www.bouncycastle.org/csharp/, but I don't how trustworthily The Legion of the Bouncy Castle is. Its seems not to be maintained frequently.

Which cryptographic primitives do I want to use?

  • Symmetric key cryptography
  • Public key cryptography with EC and RSA
  • Authentication
  • One-way hash function
  • secure number generator
  • 1
    Do you really need public domain? Or is open source enough? – CodesInChaos Sep 6 '13 at 10:15
  • Introducing a deliberate flaw in an AES implementation (beyond a timing side-channel) sounds extremely hard, especially when you compare it to adding a backdoor to the OS. – CodesInChaos Sep 6 '13 at 10:19
  • But if it is open source it can be reviewd by others. Like GnuPG was reviewed by the German Federal Office for Information Security (BSI). – dhcgn Sep 6 '13 at 11:42

If the operating system is your enemy (i.e. has potential backdoors) then you are in a bad situation indeed... because a backdoored OS can inspect everything in your application code and memory.

I suppose that your question comes from the unspoken assumption that if the .NET (Windows) implementations of cryptographic algorithms have been maliciously altered (e.g. to leak critical data elements), then maybe those backdoors would not apply to some external code ? Unfortunately, this is not the case. Indeed, the most plausible backdoor, for these matters, is to spike the system PRNG. It is possible to modify a given PRNG so that its output looks random but can be predicting by someone who is privy to the generation details. If done properly, such a backdoor cannot be detected from the outside, and even if he problem is revealed (through reverse-engineering of the PRNG implementation), one can always claim incompetence rather than malice (the Debian maintainers managed to do exactly that).

To give an example, imagine a PRNG which works by encrypting a 16-byte counter with AES, the key being a 16-byte seed obtained through hashing "random events" such as timings of hardware interrupts. Then, suppose that some unfortunate programming bug in copying the hash output into the output results in about 80 bits of the key to be predictable. Attackers who know this flaw can predict the PRNG output by doing an exhaustive search on the 48 remaining bits, which is not free, but highly doable with a few PC. You would say, how can you botch a memory copy that bad ? Surely it would appear quite artificial, and could not be plausibly denied. Yet the Openwall people, of John-the-Ripper fame, achieved such a failure in their bcrypt implementation.

Now, imagine a fully open-source (say, "public domain", although this notion tends to have a precise legal meaning which is much stronger than "we can see the source code") implementation of cryptographic algorithms. That code will use some keys, and such keys will have to be imported or, crucially, generated. Key generation requires usage of some good randomness. In C#/.NET code, where will you look for when you need randomness ? Your code executes in the CLR Virtual Machine which is a very abstract execution model -- meaning that everything happens in a very deterministic way, and your code cannot escape well-established rails. No way to read arbitrary bytes in RAM, for instance; hardware is abstracted away and you cannot access it directly. The bottom-line is that if you want good randomness in .NET, you have to get it from the operating system, i.e. System.Security.Cryptography.RNGCryptoServiceProvider. And then you are back to using the PRNG that could, potentially, be predicted by your enemy.

(The same point could be made about Java.)

Therefore, while using an external implementation of cryptographic algorithms is possible, it does not guarantee protection against backdoors in the cryptographic layer of the operating system.

On the other hand, there are good usability reasons to use the cryptographic algorithms provided by the OS:

  • The OS is in good position to use private keys securely, e.g. keeping them out of virtual memory or even put them in kernel space to avoid disclosure in case of some partial, non-administrator exploits.
  • By letting the OS handle the keys, you gain automatic support of smart cards and HSM.
  • The native implementation will use native code, which will offer much better performance (e.g. about ten times faster for RSA -- notably because native code can use the 64x64->128 multiplication opcodes of 64-bit x86 CPU, which are not accessible from .NET code).

To sum up, IF you believe your OS to be hostile to you, THEN you will have trouble escaping its evilness -- using "public-domain" implementations of cryptographic algorithms might not suffice for that; but you would lose some very interesting features by doing that. So I would suggest that you trust your OS and let it do the job for you. If that worries you to much, then don't switch to an open-source cryptographic library; switch to an open-source operating system altogether. There are many possibilities, with all the Linux brands, the *BSD (NetBSD, FreeBSD, OpenBSD...), even OpenIndiana (a derivative from Solaris)...

| improve this answer | |
  • Thx for this point of view! Coudn't I salt every RNGCryptoServiceProvider.GetBytes with a custom random source? Like XOR with microphone static sound? – dhcgn Sep 10 '13 at 6:59

Bouncy Castle is pretty well known and used in a fair number of production apps. I came across it myself a few times when I worked as a C# developer. However, most of the implementations in there simply piggyback off the .NET framework implementations anyway. The added value that they're selling is additional cryptographic primitives that .NET doesn't provide, and more convenient / simplified interfaces for people who don't understand how to use cryptography. However, it does have flaws and shouldn't be relied on for anything critical. It's also, to my knowledge, ever been formally reviewed by cryptographers.

That said, you should definitely use the .NET framework stuff, rather than rolling your own implementations. For a large part, it's just a managed wrapper around the underlying CAPI or CNG implementations in the operating system, so it's as trustworthy as the OS. The bits that aren't wrappers are explicitly named Managed, e.g. SHA1Managed. If you don't trust the CAPI or CNG implementations, then you shouldn't trust the rest of the OS, and your problem becomes moot anyway.

Even better, the .NET framework is shared-source. You can go review the reference source at at any time. There are plugins for Visual Studio (e.g. ReSharper) that let you right click any .NET type and jump to the source, and it'll automatically download the appropriate reference source files for your viewing. It's pretty awesome, and has helped me solve loads of bugs over the years.

So yeah, tl;dr is that the .NET framework implementations are solid, so use them. BC is also useful, but then you're adding bloat and potential licensing issues, so if you can get by without it then do so.

| improve this answer | |
  • My motivation was that Bruce Schneier wrote yesterday, that you should try to use public-domain encryption that has to be compatible with other implementations to remain secure. theguardian.com/world/2013/sep/05/… . But your answer disprove with his statement. That you have the same trust level in .Net and public-domain. Or did I misunderstood something? – dhcgn Sep 6 '13 at 9:25
  • .NET is in the public domain. You can go read its source code. It's also 100% to-spec with no added junk. You can run unit tests from the reference implementations to verify, if you'd like. Also, if the underlying CAPI or CNG implementations were broken, things like IE's SSL would fail, because it'd be incompatible with servers that use reference implementations. – Polynomial Sep 6 '13 at 9:36
  • 1
    .NET isn't in the public domain. It's not even open source. You can view the source-code, but only if you agree to a rather restrictive license. – CodesInChaos Sep 6 '13 at 10:35
  • How is "you can view the source" not "in the public domain"? And how does the license apply here? You're using it to review the efficacy of their implementation, which is allowed. – Polynomial Sep 6 '13 at 10:38
  • 1
    Public domain means there are no intellectual property (e.g. copyright) claims to the work. This is clearly not the case with the .NET Framework. – Michael Hampton Sep 7 '13 at 0:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.