Inevitably when somebody with more than a passing interest in programming develops an interest in crypto, there is an overwhelming urge to write cryptocode. Sometimes it is just the desire to implement something documented in a textbook or website. Sometimes it is the desire to implement a personal crypto design. And sometimes is is because there is a design need for crypto with no apparent ready solutions. All of these are valid desires / needs, however there are a few (well recognized) principles of cryptocoding that need to articulated.
Design your own Crypto
The first of these is sometimes referred to as Schneiers Law “any person can invent a security system so clever that she or he can’t think of how to break it.” This is not to state that any one person cannot design a good crypto algorithm, but that really good crypto algorithms are written by groups of people, and validated by much larger groups of well educated and intelligent people. In simple terms, good crypto is conceived by people who are well versed in the crypto state of art, and iteratively built on that. The concept is then successively attacked, and refined by an increasingly larger audience of crypto-experts. At some point the product may be deemed sufficient not because it has been proved to ‘completely secure’, but that a sufficiently capable group of people have determined that it is ‘secure enough’. Bottom line – There is nothing fundamentally wrong with designing your own crypto algorithm, but without years of education and experience as a cryptoanalyst, it is unlikely to be anywhere as good as current crypto algorithms. In addition good crypto is the product of teams and groups who try to attack and compromise it in order to improve it.
Writing your own Crypto
The second of these is sometimes referred to as “never roll your own crypto”. Even if we are implementing well documented, well defined, best practice algorithms – writing crypto code is fraught with risks that do not exist for general coding. These risks are based on the types of attacks that have been successful in the past. For example, timing attacks have been used to map out paths through the crypto code, buffer attacks have been used to extract keys from the crypto code, or weak entropy / keying. Of course this is primarily applicable in a production context or anytime the cryptocode is used to protect something of value. If this is being done for demonstration or educational purposes, these risks can often be recognized and ignored (unless dealing with those risks are part of the lesson goals). Bottom line – writing crypto code is hard, and writing high quality, secure / interoperable crypo code is much harder.
Kerckhoff’s Principle states “A cryptosystem should be secure even if everything about the system, except the key, is public knowledge.” Essentially this says that in a good cryptosystem, all parts of the system can be public knowledge (except the key) and not impair the effectiveness of the cryptosystem. Another perspective on this is that any cryptosystem that relies on maintaining the secrecy of the algorithm is less secure that one that only relies on a secret key.
Bruce Schneier stated “Kerckhoffs’s principle applies beyond codes and ciphers to security systems in general: every secret creates a potential failure point. Secrecy, in other words, is a prime cause of brittleness—and therefore something likely to make a system prone to catastrophic collapse. Conversely, openness provides ductility.”
When Kerckhoff’s principle is paired with Schneiers Law, which states (paraphrased) that more eyes makes better crypto, the result is that better code results from public and open development. Fortunately that is the approach used for most modern crypto, which is a very fortunate circumstance for the aspiring cryptocoder / cryptographer. It allows us to learn cryptosystems from the best cryptosystems available.
If you are interested in the best crypto documentation that United States Government publishes, review the FIPS and NIST Special Publications listed in the references below. For example, if you are interested in the best way to generate / test public-private keys, look at FIPS 186-4. The quality if the Pseudo Random numbers used in crypto is critical to security, and if you are interested in how this is done, look at NIST Special Publications 800-90a (revision 1), 90B, and 90C.
For years I have espousing the principals of “never write your own crypto” because it was clear that crypto is hard, and high quality cryptocode is only written by teams of well qualified cryptocoders. With the Snowden revelations over the last few years, it has also become obvious to me that “never write your own crypto” is also what a state player like the NSA would also encourage in order to more easily access communications through shared vulnerabilities in cryptosuites like OpenSSL. As a result I have modified my recommendation to state “In order to be a better cryptocoder / cryptographer, you should write your cryptocode and develop your own cryptosystems (for learning purposes), but should only use well qualified cryptocode in production or critical systems. ”
It is critically important that every systems engineer and cryptocoder develop an in depth understanding of crypto algorithms and cryptosystems, and the most effective method to accomplish this is by writing, testing and evaluating cryptocode / cryptosystems.
So my stronger recommendation is that everybody who can program and who has an interest in crypto should write crytocode and learn cryptocode and design cryptosystems, and from that we will have a much stronger foundation of understanding of Security Systems Engineering.