You know about the importance of securing your data.
But, how do you add industrial strength security to your program? The answer is simple: use the Windows Crypto API.
Most software developers who write programs that deal with data have written, or "borrowed," simple encryption routines that are all based on some scheme involving XOR, bit shifting, or some kind of data transposition. This may stop the casual observer, but with the increasing likelihood of data being transmitted over the Internet and the increasing threat of hackers and industrial spies, protecting your customer's data is more important than ever. Potential candidates for encryption include user passwords, employee salaries, or credit card numbers.
This article will first introduce you to the basics of data security and cryptography. Then, you will explore sample code to create a component that accesses the Microsoft-provided Windows Crypto API. If you look at the API's documentation, you may feel intimidated, as it is a very complex subject. To compound the complexity, all the examples provided in the documentation are written in VC++. Thankfully, you do not have to know any C++, as you will use a "wrapper" class in a COM object that simplifies all this work.
What is Cryptography?
A message or string is called plaintext (sometimes called cleartext). Encryption is the process of converting that message in a way that hides its contents. An encrypted message is called ciphertext. The process of converting ciphertext back to plaintext is called decryption. The art and science of keeping messages secure is known as cryptography and the people who practice this art are cryptographers. Cryptanalysis is the art and science of breaking ciphertext. The practitioners of cryptanalysis are called cryptanalysts. Lastly, the branch of mathematics encompassing both cryptography and cryptanalysis is cryptology.
A few concepts
Before implementing cryptographic functions, it's a good idea to define what you want to accomplish. Don't necessarily assume that you need to have 1024-byte keys, as it might seriously degrade your performance. There is a tradeoff between security and performance. In other words, security requirements for a website in a company's intranet will differ from a website accessed through the Internet. Some of the issues you need to consider are:
- Privacy/confidentiality. Do you want everybody to see your data? Do you want the government to be able to freely check on you? Do you allow competitors to see your secrets?
- Integrity. This is sometimes confused with Authentication. It is not concerned with the origin of the data, but with its validity. Has this data been tampered with?
- Availability. This refers to the property of being accessible and usable upon demand by an authorized entity.
- Access control. Who is allowed to see our data? Who is allowed to change it? You want to ensure that only authorized users are able to do what they are authorized to do.
- Authentication. Who signed this check? Who wrote this message?
- Identification. Who are you? Can you prove it?
I am not going to deal here with the types of attacks that can be unleashed on a computer system. I'll leave that for a future article, as the attacks are varied and many. This article will focus on the concepts of Identification, Authentication and Access Control.
Types of Cryptography
For our purposes, there are four basic types of cryptography:
- Symmetric Cryptography
- Hash Functions
- Public-Key Cryptography
- Digital Signatures
Symmetric Cryptography (also known as Secret-key Cryptography): With this form of cryptography, the same key is used for both encryption and decryption (Figure 1). The most common secret-key system used today is the Data Encryption Standard (DES) and its variants.
Hash Functions. These are typically encrypted in such a way that they cannot be easily decrypted. One example of their use is to encrypt a set of passwords in a database. When a user needs to be authenticated, a hash is performed on the entered plaintext password and the two hashes are then compared. The hash is commonly used to create a key from a plaintext password (or passphrase). That way, the client program could send only a hash and not the plaintext password through the wire.
Of course, there are weak and strong hash functions. Many of us have heard of, or have used a checksum or a Cyclical Redundancy Check (CRC) to verify the integrity of a file. But, these can be reverse-engineered and a file can be modified to generate the same checksum. Not long ago, a file's size was used as a simple way to compare two files to see if they were equal or even the same. That is an extreme example of a weak checksum! Using cryptography, an algorithm is used that creates an almost unbreakable key that can be used to verify the validity and integrity of a file.
Public-key Cryptography (also know as Asymmetric Encryption, Public-Key Infrastructure or PKI) uses different keys to encrypt and decrypt a message (Figure 2). A public key is published for all to see, generally in specialized servers available through the Internet. A private key must be used along with the public key to decrypt these messages. Encryption is performed with the public key, while decryption is done with the private key.
This allows you to send secret messages to people you haven't met and with whom you have not agreed on a secret key. It allows two people to engage in a publicly visible data exchange and, at the end of that exchange, read a shared secret that someone listening in on the conversation can't read. As Bruce Schneier says in his book, "Secrets & Lies" (see Bibliography at the end of the article), "it allows you and a friend to shout numbers at each other across a crowded coffeehouse filled with mathematicians so that when you are done, both you and your friend know the same random number, and everyone else in the coffeehouse is completely clueless."
The most well-known systems for public-key cryptography are Diffie-Hellman (named for its inventors, Whitfield Diffie, and Martin Hellman - 1976) and the systems that implement it, such as RSA, PGP, and Entrust.
Digital Signatures. A digital signature, unlike what a layperson might think, is not a digitized copy of your handwritten signature, but an encryption scheme that provides a level of authentication for messages. In many cases, authentication is more important than secrecy. Like public-key encryption, digital signatures use a pair of keys: a public key and a private key. You cannot derive one from the other. Programs like Pretty Good Privacy (PGP), which are widely available to the public, can perform digital signing of documents besides allowing you to maintain secrecy through the use of PKI. The most commonly used commercial program is RSA. The US Government uses a Digital Signature Algorithm (DSA), used in the US Digital Signature Standard (DSS).
Where can you incorporate cryptography in your software development process?
You could use a hash to encrypt passwords in a database. Most of the programs you create keep configuration information in a file somewhere. It could be a simple text file, like an INI or an XML file. It could be kept in the Windows Registry, or in a database table somewhere. There are advantages and disadvantages to each of these methods. You could keep your text file encrypted at all times and decrypt on the fly as needed by your program, ensuring access only through your user interface.
Suppose you are interested in keeping this file in plaintext so it can be viewed. But, suppose you do not want it to be modified from outside of your GUI (the same issue applies to the Registry entry). To accomplish this, you could have the program calculate a hash value when writing the information to disk. That is called our baseline. Then, whenever an authorized user wants to change the configuration, the program has to read it from disk. It then calculates a new hash of the contents and compares with the baseline to detect tampering.
The problem here is where do you keep the baseline? This is not an easy problem to solve. Generally, you would save it in a "secure" place, for example in another folder, within a restricted area of the system or perhaps on another secure computer to which this program has access. Is this more secure? Yes. Is it really secure? No.
Your levels of security depend on your needs. Difficulty, functionality, efficiency and cost have to be considered. However, there is only so much you can do. There are many weaknesses to consider. Management has to understand that there are several levels of responsibility and many of these fall outside our area as software developers.
Most of the time, when consultants or advisors explain to a client that a program is secure, the image the client gets may not be the same as intended. Many security weaknesses may already exist in the organization.
Issues to consider are:
- Company security policies.
- Security requirements (Were they voiced openly? Were they considered and included in the functional requirements document?)
- Network security and access control
- User carelessness or plain stupidity
You can use strong encryption algorithms to write very secure applications, but a weak password or a user leaving a terminal logged-in while at lunch can easily compromise the security.
How do you use cryptography in the applications you write?
All of this sounds difficult, and if you want to understand the algorithms and mathematical formulas involved, it is difficult?unless you are a skilled mathematician. Fortunately, Microsoft has provided developers with the Windows CryptoAPI. This is a set of DLLs that do a lot of the work for us. You do not have to understand the algorithms, just the underlying concepts and the interface.
The CryptoAPI is an integral part of Windows these days. Previously, it was available as the CryptoAPI SDK for Windows NT 4 and for Windows 95 OSR2. The CryptoAPI provides an abstraction layer that isolates you from the algorithm used to protect the data. An application refers to context and keys and makes calls to special functions that drive the encryption servers installed on the machine. These servers are called Cryptographic Service Providers (CSP) and are the modules that do the work of encoding and decoding data.
Figure 3 shows the three-tiered CryptoAPI programming model. An application makes calls to simplified cryptographic functions that delegate to base services. Neither the application nor the simplified functions should directly access any available CSPs.
Before adding cryptography to your applications, you should become familiar with terms such as context, session keys, exchange keys and signature keys. Context is a session established between the CryptoAPI and the client application. So, to establish a context, you must pass the name of a key container and the name of a provider to which to connect. You receive, in return, a handle that you use for all subsequent calls to the API.
To encrypt or decrypt data you need a session key. These objects have a very limited life, and they never leave the CSP, for reasons of security and privacy. You create, use and destroy them whenever you need to encrypt/decrypt. If you need to bring a session key out of the CSP for export purposes, you need to create a key "blob." Blobs are chunks of binary data that represent an encrypted version of your key.
The following is a sample of calls using VC++:
BOOL WINAPI CryptAcquireCertificatePrivateKey(
PCCERT_CONTEXT pCert,
DWORD dwFlags,
void *pvReserved,
HCRYPTPROV *phCryptProv,
DWORD *pdwKeySpec,
BOOL *pfCallerFreeProv
);
The handle returned as HCRYPTPROV is used throughout your communication with the CSP.
The documentation for the CryptoAPI is located at the MSDN Web site (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/portalapi_3351.asp?frame=true). Most, if not all, of the examples are in C. If you are not well versed in the C language, you may have some trouble. Fortunately, there are other ways to get at the API, as the call declarations are published and can be used from other languages, such as VB or Visual FoxPro.
The newest release of Visual FoxPro 7.0 comes with an object-oriented class library that acts as a wrapper to the Windows CryptoAPI. It makes the calls easy to use from any language that can consume COM objects, since VFP can produce COM (and COM+) compliant objects.
Here is a simple example. Open Visual FoxPro 7.0 and create a project with
CREATE PROJECT DoCryptoAPI
As shown in Figure 4, add the VFP-provided CryptoAPI library found in
HOME(1) + "FFC\_crypt.vcx"
Then, add the code in Listing 1 to the project.
The parameters @lcEncryptedStream and @lcDecryptedString are passed by reference, as indicated by the preceding @ sign. The project will now look as indicated in Figure 5.
Then, build the project as a Multi-threaded COM Server (dll).
This will compile and register the newly created DLL into your computer. Now, you can test this DLL with a simple table encryption routine, as in Listing 2.
The simple program in Listing 2 will open the customer table in the sample data and will request a password or passphrase. It will traverse the table, encrypting the company name in each record by calling the encryption routine from the DLL. This encapsulates (and hides) the complexities of dealing with API declarations and other setup needs that are taken care of by the DLL and the class library supplied.
After a quick check of the results, using a simple BROWSE command (LOCATE navigates to the top of the file), it will reverse the process, asking you for the password again and decrypting the file.
Now, let's try the sample DLL from a different platform. You can use MS Excel and a little VBA to do the same in this sample.
While still in Visual FoxPro, and with the pointer at the top of the file, type the following in the Command Box:
COPY TO test.xls TYPE XLS NEXT 10
This will export the first 10 records to an XLS file.
Open MS Excel (any version from Excel 97 and up will do) and load the TEST.XLS file just created. Add two simple buttons to the spreadsheet to trigger our sample code and change their captions as in Figure 7:
Double-click in the Encrypt button and the VBA Code Editor will open. Type the code in Listing 3 and Listing 4 that will take care of Decryption and Encryption.
As before, the VBA code asks for a password or passphrase and then calls our DLL to perform the work for every row.
With a little more work, other functions could be added to the DLL, such as digital signing. The algorithms used could also be changed to others like DES, Triple-DES, or RSA.
This should whet your appetite and show you how simple the CryptoAPI can be, and how little knowledge is needed to use world-class encryption in your programs.
References:
Applied Cryptography by B.Schneier, JohnWiley&Sons, Inc.,1996.
Secrets & Lies by B.Schneier, JohnWiley&Sons, Inc., 2000.
RSA Laboratories ? FAQ document ? May 2000
FIPS
Alex Feldstein