One of the first things to know about cryptography is that secure encryption doesn’t exist in the real world. The real distinction is between strong and weak encryption, and how resistant a given implementation is against a range of attacks.
As much as I’m proud of my little project, the above points are best illustrated with a critical look at XeroCrypt software, which provides something of a real world example for the Practical Cryptography (Bruce Schneier) section that discusses the programming issues. I’ve noticed the central issues here are related to how cryptographic keys are handled by the program.
The Right Programming Language
The choice of programming language is important, as some are intended for portability and others allow more direct interaction with the system. XeroCrypt is based on the .NET Framework, and developed primarily using Visual Basic, which means the application tells the .NET Framework which code objects to execute. Although some of those objects perform cryptographic functions, .NET isn’t ideal for crypto stuff unless it’s a web application. The user needs to trust the application, the Framework and the operating system. Instead, a language that allows more control of the system should be used. The most obvious choice here is C++.
Application data and processes must be stored somewhere during runtime, and this is where things go wrong without proper memory management. The OS could free system memory by moving cryptographic keys/plaintext to a swap partition, after which they become recoverable. Another program on the system, perhaps malware, could access the memory locations were the keys are stored. Or perhaps the key would be retained in memory long after it’s needed. If the software isn’t designed to prevent these things, the chances of an attacker recovering plaintext or keys is vastly increased. Again, C++ has functions that can be called within the program for dealing with this.
Layers of Abstraction
Slightly related to this are layers of abstraction between the software and hardware. XeroCrypt doesn’t interact directly with the operating system or the hardware, but instead through an interpreter that performs most the operations. The situation is roughly the same with shell scripts that are translated into something readable to the Linux kernel. As we can see, there are more layers of abstraction between the hardware and our application than exists with a compiled C++ program, and these layers present more points where vulnerabilities can exist and the cryptosystem attacked.
Computers will only do whatever programming tells them, which means the programming must specify exactly how the software should manage system memory, what happens when there’s an error, and what the users are allowed to do.
Without this, cryptographic software can be broken by crashing the system, perhaps forcing the OS to dump everything to a temporary file on the hard disk. Computers won’t distingish between code and user input, so the attacker could enter their own lines of programming during runtime, perhaps by overflowing the memory location to overwrite instructions.