CryptoHelper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / IdentityModel / System / IdentityModel / CryptoHelper.cs / 1 / CryptoHelper.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.IdentityModel 
{
    using System.IdentityModel.Tokens; 
    using System.Security.Cryptography; 
    using System.Security.Cryptography.Xml;
 
    static class CryptoHelper
    {
        static byte[] emptyBuffer;
        static RandomNumberGenerator random; 
        static Rijndael rijndael;
        static TripleDES tripleDES; 
 
        internal static byte[] EmptyBuffer
        { 
            get
            {
                if (emptyBuffer == null)
                { 
                    byte[] tmp = new byte[0];
                    emptyBuffer = tmp; 
                } 
                return emptyBuffer;
            } 
        }

        static Rijndael Rijndael
        { 
            get
            { 
                if (rijndael == null) 
                {
                    Rijndael tmp = CryptoHelper.NewRijndaelSymmetricAlgorithm(); 
                    tmp.Padding = PaddingMode.ISO10126;
                    rijndael = tmp;
                }
                return rijndael; 
            }
        } 
 
        static TripleDES TripleDES
        { 
            get
            {
                if (tripleDES == null)
                { 
                    TripleDESCryptoServiceProvider tmp = new TripleDESCryptoServiceProvider();
                    tmp.Padding = PaddingMode.ISO10126; 
                    tripleDES = tmp; 
                }
                return tripleDES; 
            }
        }

        internal static RandomNumberGenerator RandomNumberGenerator 
        {
            get 
            { 
                if (random == null)
                { 
                    random = new RNGCryptoServiceProvider();
                }
                return random;
            } 
        }
 
        internal static SHA1 NewSha1HashAlgorithm() 
        {
            if (SecurityUtils.RequiresFipsCompliance) 
                return new SHA1CryptoServiceProvider();
            else
                return new SHA1Managed();
        } 

        internal static SHA256 NewSha256HashAlgorithm() 
        { 
            return new SHA256Managed();
        } 

        internal static KeyedHashAlgorithm NewHmacSha1KeyedHashAlgorithm(byte[] key)
        {
            return new HMACSHA1(key, !SecurityUtils.RequiresFipsCompliance); 
        }
 
        internal static KeyedHashAlgorithm NewHmacSha256KeyedHashAlgorithm(byte[] key) 
        {
            return new HMACSHA256(key); 
        }

        internal static Rijndael NewRijndaelSymmetricAlgorithm()
        { 
            return SecurityUtils.RequiresFipsCompliance ? (Rijndael)new RijndaelCryptoServiceProvider() : new RijndaelManaged();
        } 
 
        internal static ICryptoTransform CreateDecryptor(byte[] key, byte[] iv, string algorithm)
        { 
            switch (algorithm)
            {
                case SecurityAlgorithms.TripleDesEncryption:
                    return TripleDES.CreateDecryptor(key, iv); 
                case SecurityAlgorithms.Aes128Encryption:
                case SecurityAlgorithms.Aes192Encryption: 
                case SecurityAlgorithms.Aes256Encryption: 
                    return Rijndael.CreateDecryptor(key, iv);
                default: 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnsupportedEncryptionAlgorithm, algorithm)));
            }
        }
 
        internal static ICryptoTransform CreateEncryptor(byte[] key, byte[] iv, string algorithm)
        { 
            switch (algorithm) 
            {
                case SecurityAlgorithms.TripleDesEncryption: 
                    return TripleDES.CreateEncryptor(key, iv);
                case SecurityAlgorithms.Aes128Encryption:
                case SecurityAlgorithms.Aes192Encryption:
                case SecurityAlgorithms.Aes256Encryption: 
                    return Rijndael.CreateEncryptor(key, iv);
                default: 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnsupportedEncryptionAlgorithm, algorithm))); 
            }
        } 

        internal static HashAlgorithm CreateHashAlgorithm(string algorithm)
        {
            switch (algorithm) 
            {
                case SecurityAlgorithms.Sha1Digest: 
                    return CryptoHelper.NewSha1HashAlgorithm(); 
                case SecurityAlgorithms.Sha256Digest:
                    return CryptoHelper.NewSha256HashAlgorithm(); 
                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnsupportedCryptoAlgorithm, algorithm)));
            }
        } 

        internal static KeyedHashAlgorithm CreateKeyedHashAlgorithm(byte[] key, string algorithm) 
        { 
            switch (algorithm)
            { 
                case SecurityAlgorithms.HmacSha1Signature:
                    return CryptoHelper.NewHmacSha1KeyedHashAlgorithm(key);
                case SecurityAlgorithms.HmacSha256Signature:
                    return CryptoHelper.NewHmacSha256KeyedHashAlgorithm(key); 
                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnsupportedEncryptionAlgorithm, algorithm))); 
            } 
        }
 
        internal static byte[] ComputeHash(byte[] buffer)
        {
            using (HashAlgorithm hasher = CryptoHelper.NewSha1HashAlgorithm())
            { 
                return hasher.ComputeHash(buffer);
            } 
        } 

        internal static byte[] GenerateDerivedKey(byte[] key, string algorithm, byte[] label, byte[] nonce, int derivedKeySize, int position) 
        {
            if ((algorithm != SecurityAlgorithms.Psha1KeyDerivation) && (algorithm != SecurityAlgorithms.Psha1KeyDerivationDec2005))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnsupportedKeyDerivationAlgorithm, algorithm))); 
            }
            return new Psha1DerivedKeyGenerator(key).GenerateDerivedKey(label, nonce, derivedKeySize, position); 
        } 

        internal static int GetIVSize(string algorithm) 
        {
            switch (algorithm)
            {
                case SecurityAlgorithms.TripleDesEncryption: 
                    return TripleDES.BlockSize;
                case SecurityAlgorithms.Aes128Encryption: 
                case SecurityAlgorithms.Aes192Encryption: 
                case SecurityAlgorithms.Aes256Encryption:
                    return Rijndael.BlockSize; 
                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnsupportedEncryptionAlgorithm, algorithm)));
            }
        } 

        internal static SymmetricAlgorithm GetSymmetricAlgorithm(byte[] key, string algorithm) 
        { 
            SymmetricAlgorithm symmetricAlgorithm;
            switch (algorithm) 
            {
                case SecurityAlgorithms.TripleDesEncryption:
                case SecurityAlgorithms.TripleDesKeyWrap:
                    symmetricAlgorithm = new TripleDESCryptoServiceProvider(); 
                    break;
                case SecurityAlgorithms.Aes128Encryption: 
                case SecurityAlgorithms.Aes192Encryption: 
                case SecurityAlgorithms.Aes256Encryption:
                case SecurityAlgorithms.Aes128KeyWrap: 
                case SecurityAlgorithms.Aes192KeyWrap:
                case SecurityAlgorithms.Aes256KeyWrap:
                    symmetricAlgorithm = CryptoHelper.NewRijndaelSymmetricAlgorithm();
                    break; 
                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnsupportedEncryptionAlgorithm, algorithm))); 
            } 
            symmetricAlgorithm.Key = key;
            return symmetricAlgorithm; 
        }

        internal static bool IsAsymmetricAlgorithm(string algorithm)
        { 
            switch (algorithm)
            { 
                case SecurityAlgorithms.DsaSha1Signature: 
                case SecurityAlgorithms.RsaSha1Signature:
                case SecurityAlgorithms.RsaSha256Signature: 
                case SecurityAlgorithms.RsaOaepKeyWrap:
                case SecurityAlgorithms.RsaV15KeyWrap:
                    return true;
                default: 
                    return false;
            } 
        } 

        internal static bool IsSymmetricAlgorithm(string algorithm) 
        {
            switch (algorithm)
            {
                case SecurityAlgorithms.DsaSha1Signature: 
                case SecurityAlgorithms.RsaSha1Signature:
                case SecurityAlgorithms.RsaSha256Signature: 
                case SecurityAlgorithms.RsaOaepKeyWrap: 
                case SecurityAlgorithms.RsaV15KeyWrap:
                    return false; 
                case SecurityAlgorithms.HmacSha1Signature:
                case SecurityAlgorithms.HmacSha256Signature:
                case SecurityAlgorithms.Aes128Encryption:
                case SecurityAlgorithms.Aes192Encryption: 
                case SecurityAlgorithms.Aes256Encryption:
                case SecurityAlgorithms.TripleDesEncryption: 
                case SecurityAlgorithms.Aes128KeyWrap: 
                case SecurityAlgorithms.Aes192KeyWrap:
                case SecurityAlgorithms.Aes256KeyWrap: 
                case SecurityAlgorithms.TripleDesKeyWrap:
                case SecurityAlgorithms.Psha1KeyDerivation:
                case SecurityAlgorithms.Psha1KeyDerivationDec2005:
                    return true; 
                default:
                    return false; 
            } 
        }
 
        internal static bool IsSymmetricAlgorithm(string algorithm, int keySize)
        {
            switch (algorithm)
            { 
                case SecurityAlgorithms.DsaSha1Signature:
                case SecurityAlgorithms.RsaSha1Signature: 
                case SecurityAlgorithms.RsaSha256Signature: 
                case SecurityAlgorithms.RsaOaepKeyWrap:
                case SecurityAlgorithms.RsaV15KeyWrap: 
                    return false;
                case SecurityAlgorithms.HmacSha1Signature:
                case SecurityAlgorithms.HmacSha256Signature:
                case SecurityAlgorithms.Psha1KeyDerivation: 
                case SecurityAlgorithms.Psha1KeyDerivationDec2005:
                    return true; 
                case SecurityAlgorithms.Aes128Encryption: 
                case SecurityAlgorithms.Aes128KeyWrap:
                    return keySize == 128; 
                case SecurityAlgorithms.Aes192Encryption:
                case SecurityAlgorithms.Aes192KeyWrap:
                    return keySize == 192;
                case SecurityAlgorithms.Aes256Encryption: 
                case SecurityAlgorithms.Aes256KeyWrap:
                    return keySize == 256; 
                case SecurityAlgorithms.TripleDesEncryption: 
                case SecurityAlgorithms.TripleDesKeyWrap:
                    return keySize == 128 || keySize == 192; 
                default:
                    return false;
            }
        } 

        // We currently call the CLR APIs to do symmetric key wrap. 
        // This ends up causing a triple cloning of the byte arrays. 
        // However, the symmetric key wrap exists now primarily for
        // the feature completeness of cryptos and tokens.  That is, 
        // it is never encountered in any Indigo AuthenticationMode.
        // The performance of this should be reviewed if this gets hit
        // in any mainline scenario.
        internal static byte[] UnwrapKey(byte[] wrappingKey, byte[] wrappedKey, string algorithm) 
        {
            SymmetricAlgorithm symmetricAlgorithm; 
            switch (algorithm) 
            {
                case SecurityAlgorithms.TripleDesKeyWrap: 
                    symmetricAlgorithm = new TripleDESCryptoServiceProvider();
                    break;
                case SecurityAlgorithms.Aes128KeyWrap:
                case SecurityAlgorithms.Aes192KeyWrap: 
                case SecurityAlgorithms.Aes256KeyWrap:
                    symmetricAlgorithm = CryptoHelper.NewRijndaelSymmetricAlgorithm(); 
                    break; 
                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnsupportedKeyWrapAlgorithm, algorithm))); 
            }
            using (symmetricAlgorithm)
            {
                symmetricAlgorithm.Key = wrappingKey; 
                return EncryptedXml.DecryptKey(wrappedKey, symmetricAlgorithm);
            } 
        } 

        internal static byte[] WrapKey(byte[] wrappingKey, byte[] keyToBeWrapped, string algorithm) 
        {
            SymmetricAlgorithm symmetricAlgorithm;
            switch (algorithm)
            { 
                case SecurityAlgorithms.TripleDesKeyWrap:
                    symmetricAlgorithm = new TripleDESCryptoServiceProvider(); 
                    break; 
                case SecurityAlgorithms.Aes128KeyWrap:
                case SecurityAlgorithms.Aes192KeyWrap: 
                case SecurityAlgorithms.Aes256KeyWrap:
                    symmetricAlgorithm = CryptoHelper.NewRijndaelSymmetricAlgorithm();
                    break;
                default: 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.UnsupportedKeyWrapAlgorithm, algorithm)));
            } 
            using (symmetricAlgorithm) 
            {
                symmetricAlgorithm.Key = wrappingKey; 
                return EncryptedXml.EncryptKey(keyToBeWrapped, symmetricAlgorithm);
            }
        }
 
        internal static void ValidateBufferBounds(Array buffer, int offset, int count)
        { 
            if (buffer == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer")); 
            }
            if (count < 0 || count > buffer.Length)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeInRange, 0, buffer.Length))); 
            }
            if (offset < 0 || offset > buffer.Length - count) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeInRange, 0, buffer.Length - count)));
            } 
        }

        internal static bool IsEqual(byte[] a, byte[] b)
        { 
            if (ReferenceEquals(a, b))
            { 
                return true; 
            }
 
            if (a == null || b == null || a.Length != b.Length)
            {
                return false;
            } 

            for (int i = 0; i < a.Length; i++) 
            { 
                if (a[i] != b[i])
                { 
                    return false;
                }
            }
            return true; 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK