Cryptography Overview

This overview does not provide in-depth coverage of cryptography, but rather it provides a high-level introduction to cryptographic concepts. For in-depth coverage of cryptography, read one of the many cryptography books available, such as Applied Cryptography by Bruce Schneier (John Wiley & Sons, Inc, 1996) or Handbook of Applied Cryptography by Alfred J. Menezes, Paul C. van Oorschot and Scott A. Vanstone (CRC Press, 2001).

Cryptography protects data from being viewed or modified and provides a secure means of communication over otherwise insecure channels. For example, data can be encrypted using a cryptographic algorithm, transmitted in an encrypted state, and later decrypted by the intended party. If a third party intercepts the encrypted data, it will be difficult to decipher.

In a typical situation where cryptography is used, two parties (A and B) communicate over an insecure channel. A and B want to ensure that their communication remains incomprehensible by anyone who might be listening. Furthermore, because A and B are in remote locations, A must be sure that the information received from B has not been modified by anyone during transmission. In addition, A must be sure that the information really does originate from B and not from someone impersonating B.

Cryptography is used to achieve the following goals:

• Confidentiality—to protect a user's identity or data from being read.
• Data integrity—to protect data from being altered.
• Authentication—to assure that data originates from a particular party.

To help achieve these goals, you can use a combination of algorithms and practices known as cryptographic primitives to create a cryptographic scheme. The following table lists the cryptographic primitives and their uses.

Cryptographic primitive Use

Shared-secret encryption (symmetric cryptography)

Performs a transformation on data, keeping the data from being read by third parties. This type of encryption uses a single, shared-secret key to encrypt and decrypt data.

Public-key encryption (asymmetric cryptography)

Performs a transformation on data, keeping the data from being read by third parties. This type of encryption uses a public/private key pair to encrypt and decrypt data.

Cryptographic signing

Ensures that data originates from a specific party by creating a digital signature that is unique to that party. This process also uses hash functions.

Cryptographic hashes

Maps data from any length to a fixed-length byte sequence. Hashes are statistically unique; a different two-byte sequence will not hash to the same value. Hashes are one-way algorithms.

Shared-Secret Encryption

Shared-secret encryption algorithms use a single secret key to encrypt and decrypt data. You must secure the key from access by unauthorized agents because any party that has the key can use it to decrypt data. Shared-secret encryption is also referred to as symmetric encryption because the same key is used for encryption and decryption. Shared-secret encryption algorithms are extremely fast (compared to public-key algorithms) and are well suited for performing cryptographic transformations on large streams of data.

Typically, shared-secret algorithms, called block ciphers, are used to encrypt one block of data at a time. Block ciphers (such as RC2, DES, 3DES, and Rijndael) cryptographically transform an input block of n bytes into an output block of encrypted bytes. If you want to encrypt or decrypt a sequence of bytes, you have to do it block by block. Because n is small (for RC2, DES, and 3DES, n = 8 bytes; for Rijindael, n = 16 [the default], n = 24, or n = 32 bytes), values larger than n must be encrypted one block at a time.

The block cipher classes provided in the base class library of the .NET Framework use a chaining mode called cipher block chaining (CBC), which uses a key and an initialization vector (IV) to perform cryptographic transformations on data. For a given secret key k, a simple block cipher that does not use an initialization vector encrypts the same input block of plain text into the same output block of cipher text. If you have duplicate blocks within your plain text stream, you will have duplicate blocks within your cipher text stream. If unauthorized users know anything about the structure of a block of your plain text, they can use that information to decipher the known cipher text block and possibly recover your key. To counteract this, information from the previous block is mixed into the process of encrypting the next block. Thus, the output of two identical plain text blocks is different. Because this technique uses the previous block to encrypt the next block, an IV is used to encrypt the first block of data. Using this system, common message headers that might be known to an unauthorized user cannot be used to reverse engineer a key.

One way to compromise data encrypted with this type of cipher is to perform an exhaustive search of every possible key. Depending on the size of the key used to perform encryption, this type of search is extremely time consuming by using even the fastest computers and is therefore unfeasible. Larger key sizes are more difficult to decipher. Although encryption does not make it theoretically impossible for an adversary to retrieve the encrypted data, it does raise the cost of doing so prohibitively. If it takes three months to perform an exhaustive search to retrieve data that is only meaningful for a few days, the exhaustive search method is impractical.

The disadvantage of shared-secret encryption is that it presumes two parties have agreed on a key and IV and communicated their values. Also, the key must be kept secret from unauthorized users. Because of these problems, shared-secret encryption is often used in conjunction with public-key encryption to privately communicate the values of the key and IV.

Assuming that A and B are two parties who want to communicate over an insecure channel, they might use shared-secret encryption as follows. Both A and B agree to use one particular algorithm (Rijndael, for example) with a particular key and IV. A composes a message and creates a network stream on which to send the message. Next A encrypts the text by using the key and IV, and then sends it across the Internet. A does not send the key and IV to B. B receives the encrypted text and decrypts it by using the previously agreed on key and IV. If the transmission is intercepted, the interceptor cannot recover the original message because the interceptor does not know the key or IV. In this scenario, the key must remain secret, but the IV does not need to remain secret. In a real world scenario, either A or B generates a secret key and uses public-key (asymmetric) encryption to transfer the secret (symmetric) key to the other party.

Public-Key Encryption

Public-key encryption uses a private key that must be kept secret from unauthorized users and a public key that can be made public to anyone. The public key and the private key are mathematically linked; data encrypted with the public key can be decrypted only with the private key, and data signed with the private key can be verified only with the public key. The public key can be made available to anyone; it is used for encrypting data to be sent to the keeper of the private key. Both keys are unique to the communication session. Public-key cryptographic algorithms are also known as asymmetric algorithms because one key is required to encrypt data while another is required to decrypt data.

Public-key cryptographic algorithms use a fixed buffer size whereas shared-secret cryptographic algorithms use a variable-length buffer. Public-key algorithms cannot be used to chain data together into streams the way shared-secret algorithms can because only small amounts of data can be encrypted. Therefore, asymmetric operations do not use the same streaming model as symmetric operations.

Two parties (A and B) might use public-key encryption as follows. First, A generates a public/private key pair. If B wants to send A an encrypted message, B asks A for A's public key. A sends B the public key over an insecure network, and then B uses this key to encrypt a message. B sends the encrypted message to A, and then A decrypts it by using A's private key. If B received A's key over an insecure channel, such as a public network, B must verify with A that B has a correct copy of A's public key. This key exchange between A and B needs to be secured, to help prevent against key exchange attacks. One method that helps secure the key exchange is for A to digitally sign the message.

However, during the transmission of A's public key an unauthorized agent might intercept the key. Furthermore, the same agent might intercept the encrypted message from B. However, the agent cannot decrypt the message with the public key. The message can only be decrypted with A's private key, which has not been transmitted. A does not use A's private key to encrypt a reply message to B, because anyone with the public key could decrypt the message. If A wants to send a message back to B, A asks B for B's public key, and then A encrypts the message by using B's public key. B then decrypts A's message by using B's associated private key.

In a real world scenario, A and B use public key (asymmetric) encryption to transfer a secret (symmetric) key and use shared-secret encryption for the remainder of their session.

Public-key encryption has a much larger keyspace, or range of possible values for the key, and is therefore less susceptible to exhaustive attacks that try every possible key. A public key is easy to distribute because it does not have to be secured. Public-key algorithms can be used to create digital signatures to verify the identity of the sender of data. However, public-key algorithms are extremely slow (compared to shared-secret algorithms) and are not designed to encrypt large amounts of data. Public-key algorithms are useful only for transferring very small amounts of data. Typically, public-key encryption is used to encrypt a key and IV that are to be used by a secret-key algorithm. After the key and IV are transferred, shared-secret encryption is used for the remainder of the session.

Digital Signatures

Public-key algorithms can also be used to form digital signatures. Digital signatures authenticate the identity of a sender (if you trust the sender's public key) and protect the integrity of data. Using a public key generated by A, the recipient of A's data can verify that A sent it by comparing the digital signature to A's data and public key.

To use public-key cryptography to digitally sign a message, A first applies a hash algorithm to the message to create a message digest. The message digest is a compact and unique representation of data. A then encrypts the message digest with a private key to create a personal signature. On receiving the message and signature, B decrypts the signature by using A's public key to recover the message digest and hashes the message by using the same hash algorithm that A used. If the message digest that B computes exactly matches the message digest received from A, B is assured that the message came from the possessor of the private key and that the data has not been modified. If B trusts that A is the possessor of the private key, then B knows that the message came from A.

Note that a signature can be verified by anyone because the sender's public key is common knowledge and is typically included in the digital signature format. This method does not retain the secrecy of the message. For the message to be secret, it must also be encrypted.