OWASP Guide to Building Secure Web Applications and Web Services, Chapter 19: Cryptography

This section of the OWASP Guide to Building Secure Web Applications and Web Services will help you ensure that cryptography is safely used to protect the confidentiality and integrity of sensitive user data.

This Content Component encountered an error

This article is provided by special arrangement with the Open Web Application Security Project (OWASP). This article is covered by the Creative Commons Share-Alike Attribution 2.5 license. You can find the latest version of this article and more free and open application security tools and documentation at http://www.owasp.org.


To ensure that cryptography is safely used to protect the confidentiality and integrity of sensitive user data.

Platforms Affected

Relevant COBIT Topics
DS5.18 – Cryptographic key management

Initially the realm of academia, cryptography has become ubiquitous thanks to the Internet. Common every day uses of cryptography include mobile phones, passwords, SSL, smart cards, and DVDs. Cryptography has permeated through everyday life, and is heavily used by many web applications.

Cryptography (or crypto) is one of the more advanced topics of information security, and one whose understanding requires the most schooling and experience. It is difficult to get right because there are many approaches to encryption, each with advantages and disadvantages that need to be thoroughly understood by web solution architects and developers.

The proper and accurate implementation of cryptography is extremely critical to its efficacy. A small mistake in configuration or coding will result in removing most of the protection and rending the crypto implementation useless.

A good understanding of crypto is required to be able to discern between solid products and snake oil. The inherent complexity of crypto makes it easy to fall for fantastic claims from vendors about their product. Typically, these are "a breakthrough in cryptography" or "unbreakable" or provide "military grade" security. If a vendor says "trust us, we have had experts look at this," chances are they weren't experts!

Cryptographic Functions
Cryptographic systems can provide one or more of the following four services. It is important to distinguish between these, as some algorithms are more suited to particular tasks, but not to others.

When analyzing your requirements and risks, you need to decide which of these four functions should be used to protect your data.

Using a cryptographic system, we can establish the identity of a remote user (or system). A typical example is the SSL certificate of a web server providing proof to the user that he or she is connected to the correct server.

The identity is not of the user, but of the cryptographic key of the user. Having an insecure key lowers the trust we can place on the identity.

The concept of non-repudiation is particularly important for financial or e-commerce solutions. Often, cryptographic tools are required to prove that a unique user has made a transaction request. It must not be possible for the user to refute his or her actions.

For example, a customer may request a transfer of monies from her account to be paid to another account. Later, she claims never to have made the request and demands the money be refunded to the account. If we have non-repudiation through cryptography, we can prove – usually through digitally signing the transaction request with their private key, that the user authorized the transaction.

More commonly, the biggest concern will be to keep information private. Cryptographic systems primarily function in this regard. Whether it be passwords during a log on process, or storing confidential medical records on a database, encryption can assure that only users who have access to the decryption key will get access to the data.

We can use cryptography to provide a means to ensure data is not viewed or altered during storage or transmission. Cryptographic hashes for example, can safeguard data by providing a secure checksum.

Cryptographic Algorithms
Various types of cryptographic systems exist that have different strengths and weaknesses. Typically, they are divided into two classes; those that are strong, but slow to run and those that are quick, but less secure. Most often a combination of the two approaches is used (e.g.: SSL), whereby we establish the connection with a secure algorithm, and then if successful, encrypt the actual transmission with the weaker, but much faster algorithm.

Asymmetric (also Public/Private Key Cryptography)
Asymmetric algorithms use two keys, one to encrypt the data, and either key to decrypt. These inter-dependent keys are generated together. One is labeled the Public key and is distributed freely. The private key must be kept secure.

Commonly referred to as Public/Private Key Cryptography, these algorithms can provide a number of different functions depending on how they are used. The most common implementation of public key cryptography is certificates. The public and private keys are encoded using one of several standardized formats that enable relatively simple transport and key management.

If we encrypt data with a user's public key (which is publicly available), we can send the data over an insecure network knowing that only the associated private key will be able to decrypt the data. We have ensured that the message is confidential.

A Certificate Authority (CA), whose public certificates are installed with browsers or otherwise commonly available, may also digitally sign public keys or certificates. We can authenticate remote systems or users via a mutual trust of an issuing CA. We trust their 'root' certificates, which in turn authenticate the public certificate presented by the server.

PGP and SSL are prime examples of a systems implementing asymmetric cryptography, using the RSA or other algorithms.

Symmetric keys share a common secret (password, pass phrase, or key). Data is encrypted and decrypted using the same key. These algorithms are very fast, but we cannot use them unless we have already exchanged keys. Common examples of symmetric algorithms are DES, 3DES and AES. DES should no longer be used.

Hash functions take some data (and possibly a key or password) and generate a unique hash or checksum. Since this is a one-way function, it is normally used to provide tamper detection.

MD5 and SHA-1 are common hashing algorithms used today. These algorithms are considered weak (see below) and are likely to be replaced after a process similar to the AES selection. New implementations should consider using SHA-256 instead of these weaker algorithms.

Key Exchange Algorithms
Lastly, we have key exchange algorithms (such as Diffie-Hellman for SSL). These allow use to safely exchange encryption keys with an unknown party.

Stream Ciphers
Stream ciphers, such as RC4, are vulnerable due to a property of stream ciphers. If you use the same key to "protect" two different documents, the keystream drops out when you XOR the two documents together, leaving the plaintexts XOR'd together. The two plain text documents can be recovered using frequency analysis.

How to determine if you're vulnerable
If you use stream ciphers, and you use the same key to protect different streams (or documents), you are at risk.

How to protect yourself

  • Do not use stream ciphers in this fashion
  • Consider using stronger symmetric algorithms such as AES

Weak Algorithms
There is much debate, as numerous 'secure' algorithms have recently been found to be cryptographically weak. This means that instead of taking 280 operations to brute force a cryptographic key, it may only take as little as 269 operations – something achievable on an average desktop.

As modern cryptography relies on being computationally expensive to break, specific standards can be set for key sizes that will provide assurance that with today's technology and understanding, it will take too long to decrypt any given key.

Therefore, we need to ensure that both the algorithm and the key size are taken into account when selecting an algorithm.

How to determine if you are vulnerable
Proprietary encryption algorithms are not to be trusted as they typically rely on 'security through obscurity' and not sound mathematics. These algorithms should be avoided if possible.

Specific algorithms to avoid:

  • MD5 has recently been found less secure than previously thought. While still safe for most applications such as hashes for binaries made available publicly, secure applications should now be migrating away from this algorithm.

  • SHA-0 has been conclusively broken. It should no longer be used for any sensitive applications.

  • SHA-1 has been reduced in strength and we encourage a migration to SHA-256, which implements a larger key size.

  • DES was once the standard crypto algorithm for encryption; a normal desktop machine can now break it. AES is the current preferred symmetric algorithm.

Cryptography is a constantly changing field. As new discoveries in cryptography are made, older algorithms will be found unsafe. Standard bodies such as NIST should be monitored for future recommendations.

Specific applications, such as banking transaction systems may have specific requirements for algorithms and key sizes.

How to protect yourself
Assuming you have chosen an open, standard algorithm, the following recommendations should be considered when reviewing algorithms:


  • Key sizes of 128 bits (standard for SSL) are sufficient for most applications
  • Consider 168 or 256 bits for secure systems such as large financial transactions

The difficulty of cracking a 2048 bit key compared to a 1024 bit key is far, far, far, more than the twice you might expect. Don't use excessive key sizes unless you know you need them. Bruce Schneier in 2002 (see the references section) recommended the following key lengths for circa 2005 threats:

  • Key sizes of 1280 bits are sufficient for most personal applications
  • 1536 bits should be acceptable today for most secure applications
  • 2048 bits should be considered for highly protected applications.


  • Hash sizes of 128 bits (standard for SSL) are sufficient for most applications
  • Consider 168 or 256 bits for secure systems, as many hash functions are currently being revised (see above).

NIST and other standards bodies will provide up to date guidance on suggested key sizes.

Design your application to cope with new hashes and algorithms:
Include an "algorithmName" or "algorithmVer" attribute with your encrypted data. You may not be able to reverse the values, but you can (over time) convert to stronger algorithms without disrupting existing users.

Key Storage
As highlighted above, crypto relies on keys to assure a user's identity, provide confidentiality and integrity as well as non-repudiation. It is vital that the keys are adequately protected. Should a key be compromised, it can no longer be trusted.

Any system that has been compromised in any way should have all its cryptographic keys replaced.

How to determine if you are vulnerable
Unless you are using hardware cryptographic devices, your keys will most likely be stored as binary files on the system providing the encryption.

Can you export the private key or certificate from the store?

  • Are any private keys or certificate import files (usually in PKCS#12 format) on the file system? Can they be imported without a password?

  • Keys are often stored in code. This is a bad idea, as it means you will not be able to easily replace keys should they become compromised.

How to protect yourself

  • Cryptographic keys should be protected as much as is possible with file system permissions. They should be read only and only the application or user directly accessing them should have these rights.

  • Private keys should be marked as not exportable when generating the certificate signing request.

  • Once imported into the key store (CryptoAPI, Certificates snap-in, Java Key Store, etc), the private certificate import file obtained from the certificate provider should be safely destroyed from front-end systems. This file should be safely stored in a safe until required (such as installing or replacing a new front end server)

  • Host based intrusion systems should be deployed to monitor access of keys. At the very least, changes in keys should be monitored.

  • Applications should log any changes to keys.

  • Pass phrases used to protect keys should be stored in physically secure places; in some environments, it may be necessary to split the pass phrase or password into two components such that two people will be required to authorize access to the key. These physical, manual processes should be tightly monitored and controlled.

  • Storage of keys within source code or binaries should be avoided. This not only has consequences if developers have access to source code, but key management will be almost impossible.

  • In a typical web environment, web servers themselves will need permission to access the key. This has obvious implications that other web processes or malicious code may also have access to the key. In these cases, it is vital to minimize the functionality of the system and application requiring access to the keys.

  • For interactive applications, a sufficient safeguard is to use a pass phrase or password to encrypt the key when stored on disk. This requires the user to supply a password on startup, but means the key can safely be stored in cases where other users may have greater file system privileges.

Storage of keys in hardware crypto devices is beyond the scope of this document. If you require this level of security, you should really be consulting with crypto specialists.

Insecure transmission of secrets
In security, we assess the level of trust we have in information. When applied to transmission of sensitive data, we need to ensure that encryption occurs before we transmit the data onto any untrusted network.

In practical terms, this means we should aim to encrypt as close to the source of the data as possible.

How to determine if you are vulnerable
This can be extremely difficult without expert help. We can try to at least eliminate the most common problems:

  • The encryption algorithm or protocol needs to be adequate to the task. The above chapter on weak keys should be a good starting point

  • We must ensure that through all paths of the transmission we apply this level of encryption

  • Extreme care needs to be taken at the point of encryption and decryption. If your encryption library needs to use temporary files, are these adequately protected?

  • Are keys stored securely? Is an unsecured file left behind after it has been encrypted?

How to protect yourself
We have the possibility to encrypt or otherwise protect data at different levels. Choosing the right place for this to occur can involve looking at both security as well as resource requirements.

Application: at this level, the actual application performs the encryption or other crypto function. This is the most desirable, but can place additional strain on resources and create unmanageable complexity. Encryption would be performed typically through an API such as the OpenSSL toolkit (www.openssl.com) or operating system provided crypto functions.

An example would be an S/MIME encrypted email, which is transmitted as encoded text within a standard email. No changes to intermediate email hosts are necessary to transmit the message because we do not require a change to the protocol itself.

Protocol: at this layer, the protocol provides the encryption service. Most commonly, this is seen in HTTPS, using SSL encryption to protect sensitive web traffic. The application no longer needs to implementing secure connectivity. However, this does not mean the application has a free ride. SSL requires careful attention when used for mutual (client-side) authentication, as there are two different session keys, one for each direction. Each should be verified before transmitting sensitive data.

Attackers and penetration testers love SSL to hide malicious requests (such as injection attacks for example). Content scanners are most likely unable to decode the SSL connection, letting it pass to the vulnerable web server.

Network: below the protocol layer, we can use technologies such as Virtual Private Networks (VPN) to protect data. This has many incarnations, the most popular being IPsec (Internet Protocol v6 Security), typically implemented as a protected 'tunnel' between two gateway routers. Neither the application nor the protocol needs to be crypto aware – all traffic is encrypted regardless.

Possible issues at this level are computational and bandwidth overheads on network devices.

Reversible Authentication Tokens
Today's web servers typically deal with large numbers of users. Differentiating between them is often done through cookies or other session identifiers. If these session identifiers use a predictable sequence, an attacker need only generate a value in the sequence in order to present a seemingly valid session token.

This can occur at a number of places; the network level for TCP sequence numbers, or right through to the application layer with cookies used as authenticating tokens.

How to determine if you are vulnerable
Any deterministic sequence generator is likely to be vulnerable.

How to protect yourself
The only way to generate secure authentication tokens is to ensure there is no way to predict their sequence. In other words: true random numbers.

It could be argued that computers can not generate true random numbers, but using new techniques such as reading mouse movements and key strokes to improve entropy has significantly increased the randomness of random number generators. It is critical that you do not try to implement this on your own; use of existing, proven implementations is highly desirable.

Most operating systems include functions to generate random numbers that can be called from almost any programming language.

Windows & .NET: On Microsoft platforms including .NET, it is recommended to use the inbuilt CryptGenRandom function (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/seccrypto/security/cryptgenrandom.asp.

Unix: For all Unix based platforms, OpenSSL is one of the recommended options (http://www.openssl.org/). It features tools and API functions to generate random numbers. On some platforms, /dev/urandom is a suitable source of pseudo-random entropy.

PHP: mt_rand() uses a Mersenne Twister, but is nowhere near as good as CryptoAPI's secure random number generation options, OpenSSL, or /dev/urandom which is available on many Unix variants. mt_rand() has been noted to produce the same number on some platforms – test prior to deployment.

Do not use rand() as it is very weak.

Java: java.security.SecureRandom within the Java Cryptography Extension (JCE) provides secure random numbers. This should be used in preference to other random number generators.

Safe UUID generation
UUIDs (such as GUIDs and so on) are only unique if you generate them. This seems relatively straightforward. However, there are many code snippets available that contain existing UUIDS.

How to determine if you are vulnerable

  • Determine the source of your existing UUIDS
    1. Did they come from MSDN?
    2. Or from a example found on the Internet?

  • Use your favorite search engine to find out

How to protect yourself

  • Do not cut and paste UUIDs and GUIDs from anything other than the UUIDGEN program or from the UuidCreate() API

  • Generate fresh UUIDs or GUIDs for each new program

Cryptography is one of pillars of information security. Its usage and propagation has exploded due to the Internet and it is now included in most areas computing. Crypto can be used for:

  • Remote access such as IPsec VPN
  • Certificate based authentication
  • Securing confidential or sensitive information
  • Obtaining non-repudiation using digital certificates
  • Online orders and payments
  • Email and messaging security such as S/MIME

A web application can implement cryptography at multiple layers: application, application server or runtime (such as .NET), operating system and hardware. Selecting an optimal approach requires a good understanding of application requirements, the areas of risk, and the level of security strength it might require, flexibility, cost, etc.

Although cryptography is not a panacea, the majority of security breaches do not come from brute force computation but from exploiting mistakes in implementation. The strength of a cryptographic system is measured in key length. Using a large key length and then storing the unprotected keys on the same server, eliminates most of the protection benefit gained. Besides the secure storage of keys, another classic mistake is engineering custom cryptographic algorithms (to generate random session ids for example). Many web applications were successfully attacked because the developers thought they could create their crypto functions.

Our recommendation is to use proven products, tools, or packages rather than rolling your own.

Further Reading

Alternatively, if we encrypt data with our private key, only our public key can decrypt – we have just proven the message's authenticity, since only our key could have generated the message.

Dig deeper on Software Security Test Best Practices



Enjoy the benefits of Pro+ membership, learn more and join.



Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to: