Chapter 20. SDL Minimum Cryptographic Standards

In this chapter:

As cryptographic research evolves and computers become faster, some cryptographic algorithms, security protocols, cryptographic key strengths, and usage are no longer deemed secure enough for software products.

To put this in perspective, the Electronic Frontier Foundation book Cracking DES claims that a specially built $1 million computer in 1993 would take, on average, about 3.5 hours to find a Data Encryption Standard (DES) key (Electronic Frontier Foundation 1998). According to Moore’s Law, $1 million in 1998 could crack a DES key in about 35 minutes. If you don’t have a spare million, spend $10,000 and you could break the key in 2.5 days. In 2006, CPU speeds are faster than in 1998, and memory is much cheaper.

This chapter outlines guidance and standards for writing new code or updating existing code covered by SDL, code which should be upgraded if advances in cryptographic research find algorithms or key sizes inadequate.

High-Level Cryptographic Requirements

The following sections describe at a very high level the basic SDL cryptographic requirements and best practices.

Cryptographic Technologies vs. Low-Level Cryptographic Algorithms

Whenever possible, use an established security standard rather than creating your own solution. For example, use SSL/TLS, IPSec, or WS-Security for protecting ephemeral on-the-wire data rather than creating your own authentication, key exchange, encryption, and integrity solutions from cryptographic primitives.

Best Practices

Best Practices

Projects are required to use standard protocols rather than low-level cryptography when possible. If you cannot use a standard protocol, have the design reviewed by the central security team.

Use Cryptographic Libraries

Do not create your own cryptographic libraries, and certainly do not create your own cryptographic algorithms. For .NET code, you should use the class libraries defined in System .Security.Cryptography namespace (Microsoft 2006a). For C/C++ code, you should use CryptoAPI (Microsoft 2006b). For scripts (VBScript or JavaScript), you should use CAPICOM (Microsoft 2001).

For correct function and method-call usage, please refer to the references section at the end of this chapter.

Best Practices

Best Practices

Projects are required to use standard cryptographic libraries rather than create unique cryptographic libraries or algorithms. Standard cryptographic libraries are operating system components specifically tasked with creating such functionality for use by others.

Cryptographic Agility

Do not hard-code the cryptographic algorithm(s) used by your application within the application code. Instead, store the cryptographic primitive(s) used in a configurable store—for example, in the registry or in an XML configuration file—where they can be updated quickly by the customer in the event of a sudden and unpredictable change in cryptographic technology. Note that tampering with any data store used in this way can compromise application behavior. Therefore, to protect the cryptographic primitives, appropriate mitigations—such as a strong access control policy that allows only trusted users to manipulate the data—should be defined for the data store. It’s also worthwhile to add the cryptographic algorithms used by the payload. For example, the following could represent an encrypted and MACd data blob (RFC 2104). Note that it might look as though you are providing a lot of useful information to an attacker, but you aren’t—the strength of an encryption algorithm, such as AES, lies solely in the quality and protection of the encryption.

<?xml version="1.0" encoding="utf-8"?>
<blob version="1.2">
  <encryption>
    <alg id="AES"
         keySize="256"
         IV="LqIfly+GY0ORE3KnBjw41g=="
         mode="CBC"
         padding="PKCS7"/>
    <data>qAuGOVVIpQBVd ...snip... m13yt1ngkY8=</data>
  </encryption>  <authentication>
    <alg id="HMACSHA56" />
    <data>1y1xAI9CywYQPvau71j6eRDqgfND1yla5Hdf02xAp20=</data>
  </authentication>

</blob>

Best Practices

Best Practices

Do not hard-code cryptographic algorithms in your code. Projects using cryptographic functions must be cryptographically “agile” to provide a way to upgrade the algorithms over time.

Default to Secure Cryptographic Algorithms

Use strong cryptographic algorithms by default. If a weak algorithm is needed for backward compatibility with older software or to comply with an industry standard, it should be a fallback, not a default, and it should be available only on an “opt-in” basis. Silently falling back to weak cryptography is considered bad practice; users should be notified if they are falling back to a weaker algorithm. System and network administrators should have the means to control whether applications can use weak algorithms in their administrative domains. Table 20-1 in the next section defines which cryptographic algorithms are acceptable for defaults.

Table 20-1. Cryptographic Algorithm Usage Guidance

Algorithm Class

Algorithms and Key Sizes That Must Be Replaced

Algorithms and Key Sizes Okay for Existing Code

Required Algorithms and Key Sizes for New Code

Symmetric Block Cipher

DES, DESX, RC2, Skipjack

3DES (112 bit or 168 bit)

AES (>= 128 bit)

Symmetric Stream Cipher

SEAL, CYLINK_MEK, RC4 (<128 bit)

RC4 (reviewed, see below, and >= 128 bit)

None—use a block cipher

Asymmetric Cipher

RSA or Diffie-Hellman (DH) (<1024 bit)

RSA or DH (1024-2047 bit)

RSA or DH (>=2048 bit)

Elliptic Curve Cryptography (ECC) (>=256 bit)

Hash (includes Hashed Message Authentication Codes [HMAC])

SHA0, MD2, MD4 and MD5

SHA1

SHA256, SHA384 and SHA512 (also referred to as the SHA2 algorithms)

MAC key length

<112 bit

112–127 bits

>=128 bits

Best Practices

Best Practices

If a project uses multiple cryptographic algorithms to maintain backward compatibility, it must not default or silently fall back to the cryptographic algorithms that are listed as “. . . Must Be Replaced” in Table 20-1.

Cryptographic Algorithm Usage

This section focuses on how different algorithms should be approached in new and earlier code. The SDL requirements dictate that

  • New code uses only algorithms and key lengths from the rightmost column.

  • Algorithms listed in the middle column are to be used only for backward compatibility.

  • Algorithms and key lengths listed in the left column are not to be used in shipping products without an exception from the central security team.

Using any cryptographic algorithms that are not listed in the middle or right-hand columns requires an exception from your central security team. Be aware that the United States federal government mandates the use of specific cryptographic algorithms (NIST 2005).

Symmetric Block Ciphers and Key Lengths

For symmetric block encryption algorithms, a minimum key length of 128 bits is required for new code (KeyLength 2006). The only block encryption algorithm recommended for new code is AES. (AES-128, AES-192, and AES-256 are all acceptable.) Two-key (112-bit) or three-key (168-bit) 3DES are currently acceptable if already in use in existing code. However, transitioning to AES is highly recommended. DES, DESX, RC2, and SKIPJACK are no longer considered secure; continued use of these algorithms should be for opt-in backward compatibility only.

Best Practices

Best Practices

For projects using symmetric block ciphers, AES is required for new code, and two- or three-key 3DES is permissible for backward compatibility. All other symmetric block cipher usage, including RC2, DES, DESX, and SKIPJACK, can be used only for decrypting old data.

Symmetric Stream Ciphers and Key Lengths

For symmetric stream ciphers, there is currently no recommended algorithm—you should use a block cipher, such as AES, with at least 128 bits of key material. Existing code that uses RC4 should be using a key size of at least 128 bits, and your application’s use of RC4 should be reviewed by a cryptographer. This last point is very important—there are numerous subtle errors that can arise when using stream ciphers such as RC4. Refer to the "References" section of this chapter for other material outlining some of the common errors.

Best Practices

Best Practices

The RC4 stream cipher should be used with extreme caution, and any use of the algorithm should be reviewed by a cryptographer.

Best Practices

Best Practices

All stream cipher usages must undergo a security review. RC4 with 128-bit length key or greater is permissible, but only after a security review. All other usage, including RC4 <128 bit key, is permissible only for decrypting old data.

Symmetric Algorithm Modes

Symmetric algorithms can operate in a number of modes, most of which link together the encryption operations on successive blocks of plaintext and ciphertext. The electronic code book (ECB) mode of operation should not be used without signoff from the central security team. Cipher-block-chaining (CBC) is the recommended mode of operation for block ciphers. If, for interoperability reasons, you believe that you need to use another chaining mode, you should talk to the security team.

Best Practices

Best Practices

Projects using symmetric encryption algorithms must use CBC.

Asymmetric Algorithms and Key Lengths

For RSA-based asymmetric encryption and digital signatures, the minimum acceptable key length is 1024 bits, and 1024-bit signature keys should be used only for signatures with validity periods of one year or less. New code should use RSA keys of at least 2048 bits in length.

For DSA-based digital signatures, only 1024-bit keys should be used (the maximum allowed by the DSA standard) and then only for short-lived signatures (less than one year).

For key exchange and digital signatures that are based on elliptic curve cryptography (ECC), the three NIST-approved curves—P-256, P-384, and P-521—are all acceptable.

For key agreement, Diffie-Hellman is recommended, with 2048-bit keys for new code and 1024-bit keys for backward compatibility. Keys of 512 bits or fewer are not to be used at all.

Best Practices

Best Practices

For projects using asymmetric algorithms, ECC with >=256-bit keys or RSA with >=2048-bit keys is required for new code. RSA with >=1024-bit keys is permissible for backward compatibility. RSA <1024-bit keys can be used only for decrypting old data. ECC-based key exchange and digital signatures must use one of the three NIST-approved curves—P-256, P-384, and P521 are all acceptable. For key agreement, Diffie-Hellman is recommended, with >=2048-bit keys for new code, >=1024-bit keys for backward compatibility, and no keys using <1024 bits.

Hash Functions

No new code should use the MD4 or MD5 hash algorithms because hash collisions have been demonstrated for both algorithms, which effectively “breaks” them in the eyes of the cryptographic community. Continued use of SHA-1 is permissible in existing code for backward compatibility purposes and, as described in the next Best Practices reader aid, for new code running on certain down-level platforms. The SHA-2 family of hash functions (SHA-256, SHA-384, or SHA-512) is currently the only group that is generally recommended. The SHA-2 hash functions are available in .NET code and in unmanaged Microsoft Win32 code targeting Windows Server 2003 SP1 and Windows Vista.

Note that hash function agility—the ability to switch to another hash function without updating your code—is part of the cryptographic agility requirement discussed earlier in this chapter. Absent a backward compatibility requirement, code that uses SHA-1 must migrate to SHA-2 once SHA-2 is available on the platform.

Best Practices

Best Practices

For .NET code, use of a SHA-2 hash function is required. For new native Win32 code shipping to Windows Server 2003 SP1 or Windows Vista, use of a SHA-2 hash function is required. For new native Win32 code shipping to earlier operating systems (including Windows 95, Windows 98, Microsoft Windows NT 4, and Windows 2000), use of SHA-1 is permitted. This exemption automatically expires if a service pack containing SHA-2 support ships on the platform in question. Continued use of SHA-1 is permissible for backward compatibility. All others hash functions, including MD2, MD4, and MD5, should not be used.

Message Authentication Codes

The most common and well-known message authentication code (MAC) function is the HMAC, which uses a hash function and secret MAC key for message authentication. It uses an underlying hash function (MD5, SHA-1, or SHA-2) and a secret key of a specified length. The strength of an HMAC relies on the strength of the underlying hash function and the length of the secret.

Best Practices

Best Practices

For HMAC usage, SHA-2 with >=128-bit keys is required for new code. SHA-1 with >=128-bit keys is permissible for backward compatibility. All other keys lengths <112 bits or hash functions, including MD2, MD4, or MD5, should not be used.

Data Storage and Random Number Generation

In this section, I will discuss issues related to cryptography, including sensitive data storage and generating random numbers.

Storing Private Keys and Sensitive Data

Keys, secret data, and passwords should be protected using the Data Protection API (DPAPI). Applications must not embed private keys, encrypted or not, in code.

Best Practices

Best Practices

Projects must use DPAPI to store secret data and passwords.

Generating Random Numbers and Cryptographic Keys

Security code and code using cryptographic algorithms require random numbers that exhibit unpredictability. Pseudorandom functions, such as the C runtime function rand or system functions such as GetTickCount, should therefore never be used in such code. Instead, one of the following functions or methods should be used:

  • CryptGenRandom (for C/C++ code)

  • rand_s (new C runtime library function that calls CryptGenRandom)

  • RNGCryptoServiceProvider (for .NET code)

  • GetRandom (CAPICOM for script languages)

Best Practices

Best Practices

If a project is using random numbers for cryptographic purposes, it must use CryptGenRandom, rand_s, RNGCryptoServiceProvider, or GetRandom.

Generating Random Numbers and Cryptographic Keys from Passwords or Other Keys

It’s sometimes necessary to use a password or other secret data to derive cryptographic keys, typically combined with random data such as a nonce or a salt. Using a password directly as an encryption key is not allowed. Direct hashing of the password should never be used to derive session (ephemeral) keys. Direct hashing of the password should not be used to derive long-term (static) secret or private keys.

The supported way to derive cryptographic keys from passwords or other secret data is to use a well-defined and analyzed key derivation function (KDF) (RFC 2898) such as CryptDeriveKey in CAPI and PasswordDeriveBytes or Rfc2898DeriveBytes for .NET code.

Best Practices

Best Practices

If a project derives cryptographic keys from passwords, it needs to use a key derivation function.

References

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset