Cryptography


Cryptography is one of the most important tools that you can use to protect data. Encryption can be used to provide data privacy and hash algorithms, which produce a fixed and condensed representation of data, can be used to make data tamperproof. Also, digital signatures can be used for authentication purposes.

You should use encryption when you want data to be secure in transit or in storage. Some encryption algorithms perform better than others while some provide stronger encryption. Typically, larger encryption key sizes increase security.

Two of the most common mistakes made when using cryptography are developing your own encryption algorithms and failing to secure your encryption keys. Encryption keys must be handled with care. An attacker armed with your encryption key can gain access to your encrypted data.

The main issues to consider are:

  • Use platform-provided cryptographic services

  • Key generation

  • Key storage

  • Key exchange

  • Key maintenance

Use Platform-provided Cryptographic Services

Do not create your own cryptographic implementations . It is extremely unlikely that these implementations will be as secure as the industry standard algorithms provided by the platform; that is, the operating system and the .NET Framework. Managed code should use the algorithms provided by the System.Security.Cryptography namespace for encryption, decryption, hashing, random number generating, and digital signatures.

Many of the types in this namespace wrap the operating system CryptoAPI, while others implement algorithms in managed code.

Key Generation

The following recommendations apply when you create encryption keys:

  • Generate random keys .

  • Use PasswordDeriveBytes for password-based encryption .

  • Prefer large keys .

Generate Random Keys

If you need to generate encryption keys programmatically, use RNGCryptoServiceProvider for creating keys and initialization vectors and do not use the Random class. Unlike the Random class, RNGCryptoServiceProvider creates cryptographically strong random numbers which are FIPS-140 compliant. The following code shows how to use this function.

 using System.Security.Cryptography; . . . RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); byte[] key = new byte[keySize]; rng.GetBytes(key); 

Use PasswordDeriveBytes for Password-Based Encryption

The System.Security.Cryptography.DeriveBytes namespace provides PasswordDeriveBytes for use when encrypting data based on a password the user supplies . To decrypt, the user must supply the same password used to encrypt.

Note that this approach is not for password authentication. Store a password verifier in the form of a hash value with a salt value order to authenticate a user's password. Use PasswordDeriveBytes to generate keys for password-based encryption.

PasswordDeriveBytes accepts a password, salt, an encryption algorithm, a hashing algorithm, key size (in bits), and initialization vector data to create a symmetric key to be used for encryption.

After the key is used to encrypt the data, clear it from memory but persist the salt and initialization vector. These values should be protected and are needed to re-generate the key for decryption.

For more information about storing password hashes with salt, see Chapter 14, "Building Secure Data Access."

Prefer Large Keys

When generating an encryption key or key pair, use the largest key size possible for the algorithm. This does not necessarily make the algorithm more secure but dramatically increases the time needed to successfully perform a brute force attack on the key. The following code shows how to find the largest supported key size for a particular algorithm.

 private int GetLargestSymKeySize(SymmetricAlgorithm symAlg) {   KeySizes[] sizes = symAlg.LegalKeySizes;   return sizes[sizes.Length].MaxSize; }     private int GetLargestAsymKeySize(AsymmetricAlgorithm asymAlg) {   KeySizes[] sizes = asymAlg.LegalKeySizes;   return sizes[sizes.Length].MaxSize; } 

Key Storage

Where possible, you should use a platform-provided encryption solution that enables you to avoid key management in your application. However, at times you need to use encryption solutions that require you to store keys. Using a secure location to store the key is critical. Use the following techniques to help prevent key storage vulnerabilities:

  • Use DPAPI to avoid key management .

  • Do not store keys in code .

  • Restrict access to persisted keys .

Use DPAPI to Avoid Key Management

DPAPI is a native encryption/decryption feature provided by Microsoft Windows 2000. One of the main advantages of using DPAPI is that the encryption key is managed by the operating system, because the key is derived from the password that is associated with the process account (or thread account if the thread is impersonating) that calls the DPAPI functions.

User Key vs. Machine Key

You can perform encryption with DPAPI using either the user key or the machine key. By default, DPAPI uses a user key. This means that only a thread that runs under the security context of the user account that encrypted the data can decrypt the data. You can instruct DPAPI to use the machine key by passing the CRYPTPROTECT_LOCAL_MACHINE flag to the CryptProtectData API. In this event, any user on the current computer can decrypt the data.

The user key option can be used only if the account used to perform the encryption has a loaded user profile. If you run code in an environment where the user profile is not loaded, you cannot easily use the user store and should opt for the machine store instead.

Version 1.1 of the .NET Framework loads the user profile for the ASPNET account used to run Web applications on Windows 2000. Version 1.0 of the .NET Framework does not load the profile for this account, which makes using DPAPI with the user key more difficult.

If you use the machine key option, you should use an ACL to secure the encrypted data, for example in a registry key, and use this approach to limit which users have access to the encrypted data. For added security, you should also pass an optional entropy value to the DPAPI functions.

Note  

An entropy value is an additional random value that can be passed to the DPAPI CryptProtectData and CryptUnprotectData functions. The same value that is used to encrypt the data must be used to decrypt the data. The machine key option means that any user on the computer can decrypt the data. With added entropy, the user must also know the entropy value.

The drawback with using entropy is that you must manage the entropy value as you would manage a key. To avoid entropy management issues, use the machine store without entropy and validate users and code (using code access security) thoroughly before calling the DPAPI code.

For more information about using DPAPI from ASP.NET Web applications, see "How To: Create a DPAPI Library," in the How To section of "Building Secure ASP.NET Applications," at http://msdn.microsoft.com/library/en-us/dnnetsec/html/SecNetHT07.asp .

Do Not Store Keys in Code

Do not store keys in code because hard-coded keys in your compiled assembly can be disassembled using tools similar to ILDASM, which will render your key in plaintext.

Restrict Access to Persisted Keys

When storing keys in persistent storage to be used at runtime, use appropriate ACLs and limit access to the key. Access to the key should be granted only to Administrators, SYSTEM, and the identity of the code at runtime, for example the ASPNET or Network Service account.

When backing up a key, do not store it in plain text, encrypt it using DPAPI or a strong password and place it on removable media.

Key Exchange

Some applications require the secure exchange of encryption keys over an insecure network. You may need to verbally communicate the key or send it through secure email. A more secure method to exchange a symmetric key is to use public key encryption. With this approach, you encrypt the symmetric key to be exchanged by using the other party's public key from a certificate that can be validated . A certificate is considered valid when:

  • It is being used within the date ranges as specified in the certificate.

  • All signatures in the certificate chain can be verified .

  • It is of the correct type. For example, an e-mail certificate is not being used as a Web server certificate.

  • It can be verified up to a trusted root authority.

  • It is not on a Certificate Revocation List (CRL) of the issuer.

Key Maintenance

Security is dependent upon keeping the key secure over a prolonged period of time. Apply the following recommendations for key maintenance:

  • Cycle keys periodically .

  • Protect exported private keys .

Cycle Keys Periodically

You should change your encryption keys from time to time because a static secret is more likely to be discovered over time. Did you write it down somewhere? Did Bob the administrator with the secrets change positions in your company or leave the company? Are you using the same session key to encrypt communication for a long time? Do not overuse keys.

Key Compromise

Keys can be compromised in a number of ways. For example, you may lose the key or discover that an attacker has stolen or discovered the key.

If your private key used for asymmetric encryption and key exchange is compromised, do not continue to use it, and notify the users of the public key that the key has been compromised. If you used the key to sign documents, they need to be re-signed.

If the private key of your certificate is compromised, contact the issuing certification authority to have your certificate placed on a certificate revocation list. Also, change the way your keys are stored to avoid a future compromise.

Protect Exported Private Keys

Use PasswordDeriveBytes when you export an Rivest, Shamir, and Adleman (RSA) or Digital Signature Algorithm (DSA) private key. The RSA and DSA classes contain a ToXmlString method, which allows you to export the public or private key, or both, from the key container. This method exports the private key in plain text. If you export the private key to be installed on multiple servers in a Web farm, a recommended method is to encrypt the key after exporting the private key by using PasswordDeriveBytes to generate a symmetric key as shown in the following code sample.

 PasswordDeriveBytes deriver = new PasswordDeriveBytes(<strong password>, null); byte[] ivZeros = new byte[8];//This is not actually used but is currently required. //Derive key from the password byte[] pbeKey = deriver.CryptDeriveKey("TripleDES", "SHA1", 192, ivZeros); 



Improving Web Application Security. Threats and Countermeasures
Improving Web Application Security: Threats and Countermeasures
ISBN: 0735618429
EAN: 2147483647
Year: 2003
Pages: 613

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net