11

In c#, there is a namespace called System.Security.Cryptography and there are many classes in this namespace, which help developers encrypt and decrypt data. However, always they take byte[] array and they return byte[] array. So, as a developer, you have to always write a library to get the clear-text, turn it into byte of arrays, encrypt it, then turn the cipher array into an string, and return it.

I've talked to some other PHP and Java developers, and they told me that they have to undergo the same process there too. I haven't seen those languages though.

My question is, why frameworks like .NET framework, don't provide an straightforward mechanism for encryption and decryption? I mean, from the point of view of a developer, cryptography means a black box into which you pass a string, and from which you will get an string, without the need to get into the complexity of creating streams like CryptoStream and without the need to converting strings into bytes of arrays, etc.

For example, look at this simple encryption example, taken from Microsoft's MSDN:

    static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
    {
        // Check arguments.
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException("plainText");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException("Key");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("Key");
        byte[] encrypted;
        // Create an Rijndael object
        // with the specified key and IV.
        using (Rijndael rijAlg = Rijndael.Create())
        {
            rijAlg.Key = Key;
            rijAlg.IV = IV;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

            // Create the streams used for encryption.
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {

                        //Write all data to the stream.
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }


        // Return the encrypted bytes from the memory stream.
        return encrypted;

    }

This is just not simple and easy, and I think there should be a class in .NET Framework like TripleDesCryptoHelper with two methods as follow:

public string Encrypt(string clearText)
{
    // Doing the cryptography stuff here
    return cipherText;
}

public string Decrypt(string cipherText)
{
   // Doing the cryptography stuff here
   return clearText;
}
Saeed Neamati
  • 211
  • 2
  • 4
  • 1
    If you are free in the choice of your cryptographic algorithms, you can use NaCl (http://nacl.cace-project.eu/index.html) for your C, C++ and Python projects. Its secure, fast and resistant against timing attacks. – j.p. Jan 03 '12 at 12:52
  • Can anyone provide examples of security failures that resulted from the lack of ease of use of Encryption libraries? – Ethan Heilman Jan 03 '12 at 16:08
  • 4
    @EthanHeilman in my opinion, any library that does not provide integrity checks/authentication by default for encryption is already luring users into a pretty sweet trap, and if you use e.g. "AES" algorithm in Java, it will default to "AES/ECB/PKCS5Padding" and ECB is not what you want. Besides, security requirements change in time, and once you've introduced a default setting, you cannot change it afterwards without breaking everything. – Maarten Bodewes Jan 03 '12 at 19:46
  • 2
    @EthanHeilman Look at some encryption questions/answers on stackoverflow. Most of them have huge holes, such as no authentication(hello padding oracle) or constant IVs. – CodesInChaos Feb 07 '13 at 15:40
  • I am asking for serious failures in security that results in physical or financial damage. Such examples would make the case for simple easy to use packaged encryption in much the same way that firms which did not salt their passwords and had massive password exposures helped the security community "raise the bar" on password hashing standards. – Ethan Heilman Feb 20 '13 at 16:05
  • Don't confuse programming languages with libraries! C# is a language .NET is a library/framework. It's not the language's business to provide cryptography, it's the library's. – Calmarius Jun 01 '18 at 15:22

3 Answers3

25

It's not nearly as simple as you imagine. When you encrypt a string, what character set is it in? What characters are permissible in the output? There are too many unusual combinations of code requirements and security requirements for a "one size fits all" to make sense.

But if you think one size does fit all, sit down and write it. It should take you an hour or so. You'll have it forever, can share it with other people, and this problem will be solved. I think you'll find everyone needs it to be a little different and you'll be right back where we are.

Here's a function to set the character set. Here's a function to switch between hex and base64. Here's a function to add padding. Here's a function to add a checksum. Here's a function to set the key in hex. Here's a function to set the key in base64. And so on, and so on, and so on.

Fundamentally, encryption is not easy. Threat models differ. Requirements differ. One simple "this encrypts" interface is much more likely to be used to disastrous results than good ones.

There's also the attractive nuisance issue -- things that are neither easy nor safe probably should not look easy and safe.

David Schwartz
  • 4,729
  • 19
  • 31
  • 5
    You are right. I never said that one-fit-all solution is a good one. But I said that frameworks could include both the easy version as well as the sophisticated one. For example, concatenating strings is possible both via StringBuilder class, and string.Format() method. The second one is more handy when it comes to simple placeholders. – Saeed Neamati Jan 03 '12 at 14:31
  • 3
    String concatenation does not change in time. Crypto requirements do, and you cannot change defaults afterwards, because all the old code will break. Currently I would e.g. default to AES in EAX mode, but most frameworks may not even support that, and maybe you want to switch over later to single pass encryption/authentication (once that frickin patent finally expires) – Maarten Bodewes Jan 03 '12 at 19:51
  • "Frameworks could include both the easy version as well as the sophisticated one." The problem there is that there isn't one single "sophisticated" crypto scheme that a library could include by default. There are, as David Schwartz said, varying needs for varying applications of cryptography. – Joe Z. Jan 15 '13 at 03:48
  • 1
    Let's not forget that cryptography is restrained or even illegal in many countries, and as such limits the distribution of the language if included. – orlp Feb 08 '13 at 21:02
3

I've seen some libraries that offer simplified cryptography methods, but as that was a long time ago (like 15-20 years) because they only handled ASCII strings, with your choice of Base64 or Hex output. But as David pointed out things are much more complicated. Most systems handle Unicode and different character encodings.

There probably are simplified libraries for some systems that make it easier to do simple string cryptography. And those would be useful for working on "school assignments" and modeling simple scenarios like on here, but for actual work they wouldn't be useful anymore.

Say you wanted to encrypt email. Sure, it is just plain text right? But what if the email supports international character sets? How about binary attachments? Well, now it is a combination of "plain text" and binary data. What should the system output when it is done? Hexadecimal would be a bad choice because it takes a lot more bytes to represent the same data. So go with Base64 output? That makes since, but if you are writing it to a file, or streaming it through another mechanism then you want it as regular binary data to take up less space (base 64 adds like a 30% size overhead if I remember correctly).

What you will most likely do is create a mid to high level layer for each specific cryptography application you are creating. Chances are you will probably reuse some of that between applications too.

Jim McKeeth
  • 931
  • 8
  • 16
0

The reason is that different libraries offer different functionality. There are libraries that offer relatively easy to use encryption methods. How ever you may want to use a library that offers a more complex method. The language allows for a common syntax. The methods you are mentioned are part of the libraries. The libraries take the core syntax and give developers the ability to do complex things with relatively simple commands with out having to know and understand all of the underlying common machine language functionality.

So your question really should be "Why are there no popular encryption methods that are easy to use?"... The reason is that if it is simple to use then it is simple to use the decryption method to easily decrypt. This means that anyone could use that simple .Decrypt(string) method to get your original message. There are some canned libraries that will do the string encryption natively. But the language allows you to construct your own method to encrypt and decrypt so you can control how secure your data actually is.

Chad
  • 283
  • 2
  • 10
  • There is a general rule that when an engineer designs a crypto system, that system is insecure. Creating libraries that encourage the design, rather than the use, of cryptosystems is exceedingly dangerous.

    I'm not sure what you mean by the statement: "The reason is that if it is simple to use then it is simple to use the decryption method to easily decrypt." I don't think anyone is proposing simplifying away the key, nor do I think the inclusion of a key causes the needless complication seen in crypto libraries. I see no reason why one can't design a simple secure crypto library.

    – Ethan Heilman Jan 04 '12 at 21:23
  • 1
    @EthanHeilman - System.Security.Cryptography but the OP is asking for it to be a part of the core product. That is not how C# works. – Chad Jan 04 '12 at 21:49
  • 2
    My understanding is that the OP is asking for a simpler interface in which he doesn't have to figure out how to generate an IV, choose the block cipher to use, and manage streams. Note that IV management can decide the security of a system as happened in the BEAST attack. Does ICryptoTransform provide padding, authentication, chaining? Is it running in ECB mode? How does it handle abrupt interruptions in the input stream? Wouldn't a nice (utf-8string, key) => authenticated non-mutatable ciphertext library prevent more errors than not? Shouldn't it be something we are striving toward? – Ethan Heilman Jan 04 '12 at 22:28
  • @EthanHeilman - And my point is that there are libraries that do this. And C# is set up so that you can create a your own library to handle encryption the way you want. It is not natively part of the .net framework because not everyone wants to do encryption the same way... not to mention encryption export restrictions. – Chad Jan 05 '12 at 14:00
  • 1
    Creating your own encryption library is a recipe for distaster. Most people using encryption do understand exactly what they want so providing an easy option that doesn't default to ECB and includes authentication and padding turned on by default would be extremely helpful.

    I'd be curious to see any libraries that do encryption in a simple and secure manner (simplicity and security are proportionally linked in my experience). I'm not saying they don't exist, I'd really like to discover that such libraries are common and available for most languages, I just haven't run into them.

    – Ethan Heilman Jan 05 '12 at 15:06
  • @EthanHeilman - I am not suggesting that just anyone should create their own encryption library. Just that .net is set up so that you can. but then again simple and secure are relative. To me the code that the OP finds complex is quite simple and basic. There are standard encoding techniques that are little more than obfuscation of the data. Makes it hard to read easily not hard to get the data out. (System.Text.Encoding) This Question on SO has some slightly more complicated but still simple solutions too. – Chad Jan 05 '12 at 17:27
  • @EThanHeilman - I am also not trying to address "How SHOULD programming languages implement encryption?" _ The question is "Why programming languages don't provide simple encryption methods?" (Specifically C# according to the text) The other question is out of my scope. – Chad Jan 05 '12 at 17:34
  • I think David Schwartz gave a decent partial answer to "Why programming languages don't provide simple encryption methods?", but it concerns me that the question assumes that there is a good reason why programming languages don't provide a simple secure encryption system rather than insist that users roll their own. I don't have a good answer why they don't but I'm using this question as a soapbox to insist that they should (I think this was probably the original intend of the OP). – Ethan Heilman Jan 05 '12 at 22:35
  • @EthanHeilman - The solution that the OP finds difficult is not a roll your own encryption it is creating a method to leverage System.Security.Cryptography. Any canned solution is going to be compromised eventually. So the framework would have to be patched... we already have enough problems with servers not being patched for vulnerabilities with out adding another avenue for hackers to attack. – Chad Jan 06 '12 at 13:52
  • "Any canned solution is going to be compromised eventually." I strongly disagree with this statement. A well thought out, tested and understood standard that has undergone extensive review by the crypto community has a much better change of avoiding compromise than a system designed by a single engineer using a fairly low level library. If languages are serious about security as a feature such secure crypto-systems should be the easiest option available to a engineer. As a general rule I see no reason excuse for not designing libraries to be secure by default, most secure option is easiest. – Ethan Heilman Jan 06 '12 at 14:41
  • @EthanHeilman - If we create a default crypto solution and all languages implement that or even if it is just for a single popular method then any comprimise of that solution be it a weakness in the crpto or the implementation of the crypto means that an attacker can exploit a vast majority of applications written in that language. By not having a default implementation there are some apps that are less secure but an attacker would still need to figure out how what is there is implemented adding a hopefully non trivial step for a well secured app. – Chad Jan 09 '12 at 14:34
  • While what you say has wisdom the crypto community has taken the opposite approach. Create one standard that everyone reviews, checks, vets, attacks, researches. Use that standard everywhere. For example see the selection of AES, or the current SHA3 contest.

    Some designers have suggested that NIST select the top three hash functions for SHA3 rather than only one. The argument against this is that if a protocol supports the top 3 and one of them is broken an attacker can request that the protocol use the broken function (tripling the chance of a break).

    – Ethan Heilman Jan 09 '12 at 15:55
  • @EthanHeilman - The difference is if the protocol breaks the community can choose a new one and that is the new standard. But the AES standard is not simple to implement. And that is part of what makes it secure. With a program I can crack the method that creates the IV and the AES Becomes non-trivial but not essentially crack proof. So, yes you must understand how to make an IV, while not trivial it is not an overly complex problem either. – Chad Jan 09 '12 at 16:15
  • I would argue that protocols are not easy to implement either but our discussion is getting rather off topic (off question). Would you be willing to open a question called "Is it better to have one standard protocol for each security need or should a diversity of protocols be implemented for a given security need?" I would be happy to provide a full length answer to such a question. – Ethan Heilman Jan 09 '12 at 16:27
  • And now it turns out that the AES has a back door that the NSA has access to. And if the NSA has a tool for it that tool is in the wild somewhere. – Chad Jan 02 '14 at 17:11
  • You have a source for the statement that "it turns out that the AES has a back door that the NSA has access to"? – Ethan Heilman Jan 02 '14 at 19:26