Security
Recommended Security Algorithms by USA NSA (National Security Agency of United States of America)
Algorithm Type:
Advice: If you need to send large encrypetd file then the best way is:
Speed is provided in MBps and was measured on Pentium 4 2.1 GHz processor under Windows XP SP 1 (C++ code was compiled with Microsoft Visual C++ .NET 2003 (whole program optimization, optimize for speed, P4 code generation).
Algorithm Type | Default Algorithm |
Hash (for speed) |
MD5 (128bit) System.Security.Cryptography.MD5: Invokes the currently configured default MD5 implementation. Note: Please use this algorithm only for non secure information where speed is top priority. MD5 have two major advantages: a) It is world wide de facto standard to generate checksums (hashes) for files and objects; b) Hash can be stored as GUID (Global Unique IDentifier) which also has full native support inside databases ('uniqueidentifier' type for SQL Servers and 'Number -> Replication ID' type for Microsoft Access). Some people also prefer to use "HMAC with MD5" algorithm to hash passwords and store them inside database as GUIDs. (Speed: MD5-128 - 216.67) |
Hash (for security) |
SHA-256 System.Security.Cryptography.SHA256: Invokes the currently configured default SHA-256 implementation. The default is System.Security.Cryptography.SHA256Managed in mscorlib.dll. Security.Cryptography.SHA256Managed: SHA-256, 256 bit message digest, .NET Framework library implementation in mscorlib.dll. (Speed: SHA-256 - 44.46, SHA-512 - 11.39) |
Keyed Hash |
HMAC with SHA-256. HMAC with SHA-1 may be used where interoperability
with legacy systems is critical System.Security.Cryptography.HMACSHA256: HMAC SHA-256, 256 bit message digest, .NET Framework library implementation in mscorlib.dll. The HMAC process mixes a secret key* with the message data, hashes the result with the hash algorithm, mixes that hash value with the secret key again, and then applies the hash algorithm a second time. * - The secret key for HMACSHA256 encryption can be 1-64 bytes length (recommended: 64 bytes). If it is more than 64 bytes long it will be hashed (using SHA-1) to derive a 64-byte key. The output hash is 256 bits in length. You can use SHA-1 to generate secret keys from UTF-8 strings. Or create GetRandomBytes function (example provided below). Note: This algorithm is recommended (against plain SHA-256 or HMACMD5) to store hashed passwords because aditional secret key makes dictionary attacks impossible. (Speed: SHA-256 - 44.46, SHA-512 - 11.39) |
Symmetric Encryption |
Rijndael with 256-bit cryptovariable (or AES) System.Security.Cryptography.Rijndael: Invokes the currently configured default Rijndael implementation. The default is System.Security.Cryptography.RijndaelManaged in mscorlib.dll. System.Security.Cryptography.RijndaelManaged: Rijndael, 128, 192, or 256 bit cryptovariable (default is 256), 128, 192, or 256 bit block size (default is 128), .NET Framework library implementation in mscorlib.dll. The default mode is CBC, the default padding is zeros. Note: Rijndael and AES has exactly same algorithm, except that Rijndael supports more block and key sizes. Rijndael supports block and key sizes of 128, 160, 192, 224, and 256 bits, whereas AES supports only one block size - 128 bits, and 128, 192, 256 bit key sizes. If you are planning stick to AES Standard then use Rijndael with 128bit block size and one of 128 (for "secret" info), 192, or 256 (for "top secret" info) bit for the key size. (Speed: AES-128 - 61.01, AES-192 - 53.15, AES-256 - 48.23) Note: Triple DES (168-bit cryptovariable) may be used where interoperability with legacy systems is critical. |
Asymmetric Encryption |
RSA with 2048-bit key System.Security.Cryptography.RSA: Invokes the currently configured default RSA implementation. The default is System.Security.Cryptography.RSACryptoServiceProvider in mscorlib.dll. System.Security.Cryptography.RSACryptoServiceProvider: RSA, default key size is 1024 bits. This invokes managed code in mscorlib.dll (System.Security.Cryptography.RSACryptoServiceProvider) that wraps the Windows operating system default “PROV_RSA_FULL” type CSP implementation of RSA. |
Pseudo-Random Number Generator |
Microsoft Strong Cryptographic Provider System.Security.Cryptography.RandomNumberGenerator: Invokes the currently configured default PRNG. The default is System.Security.Cryptography.RNGCryptoServiceProvider in mscorlib.dll. System.Security.Cryptography.RNGCryptoServiceProvider: This service invokes managed code in mscorlib.dll (System.Security.Cryptography.RNGCryptoServiceProvider) that wraps calls to any specified installed CSP. The default is the “PROV_RSA_FULL” type implementation for the Microsoft Strong Cryptographic Provider. |
Digital Signature: |
RSA PKCS #1 version 1.5 digital signature with 2048-bit key
size System.Security.Cryptography.RSAPKCS1SignatureFormatter, System.Security.Cryptography.RSAPKCS1SignatureDeformatter: RSA PKCS #1 version 1.5 digital signature. Must be invoked with a named hash service and any implementation of RSA specified, as no defaults are defined. |
XML Digital Signature Transforms: |
http://www.w3.org/2000/09/xmldsig#base64 (or any) http://www.w3.org/2000/09/xmldsig#base64: Invokes the currently configured Base64 decoding algorithm. The default is the .NET Framework library implementation System.Security.Cryptography.Xml.XmlDsigBase64Transform in system.security.dll. |
Key Exchange |
RSA PKCS #1 version
1.5 key exchange with 2048-bit key size System.Security.Cryptography.RSAPKCS1KeyExchangeFormatter, System.Security.Cryptography.RSAPKCS1KeyExchangeDeformatter: RSA PKCS #1 version 1.5 key exchange. Must be invoked with a specific implementation of RSA, as no default is defined. |
Here was a heap that some libraries contains "backdoors". For example it has been disclosed that CryptoAPI (Microsoft's Cryptographic API) has a "secret" key that enables the holder of the key to sign CryptoAPI modules (these modules are known as CSPs, or Cryptographic Service Providers) - these modules can then be silently installed onto a users machine. The real big news is that this key is call _NSAKEY internally by Windows. This has led to speculation that this key is really a US's National Security Agency owned key that allows them to remotely install weakened crypto on any computer with the Windows operating system.
Microsoft NET Framework version 2.0 advice: Don't use System.String type for confidential information. Use System.Security.SecureString which represents text that should be kept confidential. The text is encrypted for privacy when being used, and deleted from computer memory when no longer needed. This class cannot be inherited. In order for this class to be effective, any .NET Framework method that reads secret data (perhaps a password from the console, or a connection string from web.config) needs to directly encapsulate that data in a SecureString and return it to you. You can't simply wrap a SecureString around a normal string and expect it to be any safer—to be effective, the secret must never ever find its way into a normal managed string.
System.Security.AccessControl - The Framework now models Windows security descriptors, allowing you to programmatically read and modify access control lists (ACL), take ownership of objects, convert between security descriptor description language (SDDL) strings and binary security descriptors, and more.
FileSecurity sd = new FileSecurity(); // block inherited ACEs sd.SetAccessRuleProtection(true, false); FileSystemRights read = FileSystemRights.ReadPermissions | FileSystemRights.ReadData | FileSystemRights.ReadAttributes | FileSystemRights.ReadExtendedAttributes; sd.AddAccessRule(new FileSystemAccessRule( new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null), FileSystemRights.FullControl, AccessControlType.Allow)); sd.AddAccessRule(new FileSystemAccessRule( new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null), read, AccessControlType.Allow)); File.SetAccessControl(@"c:\work\test.txt", sd);
// Function to print owner of file. void printTheOwnerOfThisFile(string path) { FileSecurity s = File.GetAccessControl(path); NTAccount user = (NTAccount) s.GetOwner(typeof(NTAccount)); Console.WriteLine(user); } ... printTheOwnerOfThisFile(@"c:\autoexec.bat");
// Generate specified number of random bytes public byte[] GetRandomBytes(int bytes){ // Create a random key using a random number generator. byte[] randomBytes = new Byte[bytes]; //RNGCryptoServiceProvider is an implementation of a random number generator. System.Security.Cryptography.RNGCryptoServiceProvider rng; rng = new System.Security.Cryptography.RNGCryptoServiceProvider(); // The array is now filled with cryptographically strong random bytes. rng.GetBytes(randomBytes); return randomBytes; } Example: HMAC with SHA-256 (Hash files) ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.en/cpref11/html/T_System_Security_Cryptography_HMACSHA256.htm // Calculate SHA-1 hash from UTF-8 string. public byte[] CalcSHA1(string message){ // Get bytes from UTF8 string. byte[] bytes = System.Text.UTF8Encoding.UTF8.GetBytes(message); // Create 64-bit secret key by hashing bytes with SHA1 hash algorithm. return System.Security.Cryptography.SHA1.Create().ComputeHash(bytes); } // Calculate SHA-256 hash with key generated from UTF-8 string. public byte[] CalcHMACSHA256(string key, byte[] message){ // Get hash from UTF8 string. byte[] keyHash = CalcSHA1(message); // Return 256-bit keyed hash of the message. return new System.Security.Cryptography.HMACSHA256(keyHash).ComputeHash(message); } // Calculate SHA-256 hash. public byte[] CalcHMACSHA256(byte[] key, byte[] message){ // Return 256-bit keyed hash of the message. return new System.Security.Cryptography.HMACSHA256(key).ComputeHash(message); }