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 / ServiceModel / System / ServiceModel / Security / CryptoHelper.cs / 1 / CryptoHelper.cs

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

namespace System.ServiceModel.Security 
{
    using System.Collections; 
    using System.ServiceModel.Channels; 
    using System.ServiceModel;
    using System.IO; 
    using System.Security.Cryptography;
    using System.IdentityModel.Tokens;
    using System.Text;
    using System.Xml; 

    using Psha1DerivedKeyGenerator = System.IdentityModel.Psha1DerivedKeyGenerator; 
 
    static class CryptoHelper
    { 
        static byte[] emptyBuffer;
        static readonly RandomNumberGenerator random = new RNGCryptoServiceProvider();

        enum CryptoAlgorithmType 
        {
            Unknown, 
            Symmetric, 
            Asymmetric
        } 

        internal static byte[] EmptyBuffer
        {
            get 
            {
                if (emptyBuffer == null) 
                { 
                    byte[] tmp = new byte[0];
                    emptyBuffer = tmp; 
                }
                return emptyBuffer;
            }
        } 

        internal static SHA1 NewSha1HashAlgorithm() 
        { 
            if (SecurityUtils.RequiresFipsCompliance)
                return new SHA1CryptoServiceProvider(); 
            else
                return new SHA1Managed();
        }
 
        internal static SHA256 NewSha256HashAlgorithm()
        { 
            return new SHA256Managed(); 
        }
 
        internal static HashAlgorithm CreateHashAlgorithm(string digestMethod)
        {
            switch (digestMethod)
            { 
                case SecurityAlgorithms.Sha1Digest:
                    return CryptoHelper.NewSha1HashAlgorithm(); 
                case SecurityAlgorithms.Sha256Digest: 
                    return CryptoHelper.NewSha256HashAlgorithm();
                default: 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.UnsupportedCryptoAlgorithm, digestMethod)));
            }
        }
 
        internal static HashAlgorithm CreateHashForAsymmetricSignature(string signatureMethod)
        { 
            switch (signatureMethod) 
            {
                case SecurityAlgorithms.RsaSha1Signature: 
                case SecurityAlgorithms.DsaSha1Signature:
                    return CryptoHelper.NewSha1HashAlgorithm();
                case SecurityAlgorithms.RsaSha256Signature:
                    return CryptoHelper.NewSha256HashAlgorithm(); 
                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.UnsupportedCryptoAlgorithm, signatureMethod))); 
            } 
        }
 
        internal static byte[] ExtractIVAndDecrypt(SymmetricAlgorithm algorithm, byte[] cipherText, int offset, int count)
        {
            if (cipherText == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("cipherText");
            } 
            if (count < 0 || count > cipherText.Length) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeInRange, 0, cipherText.Length))); 

            }
            if (offset < 0 || offset > cipherText.Length - count)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeInRange, 0, cipherText.Length - count)));
            } 
 
            int ivSize = algorithm.BlockSize / 8;
            byte[] iv = new byte[ivSize]; 
            Buffer.BlockCopy(cipherText, offset, iv, 0, iv.Length);
            algorithm.Padding = PaddingMode.ISO10126;
            algorithm.Mode = CipherMode.CBC;
            try 
            {
                using (ICryptoTransform decrTransform = algorithm.CreateDecryptor(algorithm.Key, iv)) 
                { 
                    return decrTransform.TransformFinalBlock(cipherText, offset + iv.Length, count - iv.Length);
                } 
            }
            catch (CryptographicException ex)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.DecryptionFailed), ex)); 
            }
        } 
 
        internal static void FillRandomBytes(byte[] buffer)
        { 
            random.GetBytes(buffer);
        }

        static CryptoAlgorithmType GetAlgorithmType(string algorithm) 
        {
            switch (algorithm) 
            { 
                case SecurityAlgorithms.DsaSha1Signature:
                case SecurityAlgorithms.RsaSha1Signature: 
                case SecurityAlgorithms.RsaSha256Signature:
                case SecurityAlgorithms.RsaOaepKeyWrap:
                case SecurityAlgorithms.RsaV15KeyWrap:
                    return CryptoAlgorithmType.Asymmetric; 
                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 CryptoAlgorithmType.Symmetric;
                default: 
                    return CryptoAlgorithmType.Unknown;
            }
        }
 
        internal static byte[] GenerateIVAndEncrypt(SymmetricAlgorithm algorithm, byte[] plainText, int offset, int count)
        { 
            byte[] iv; 
            byte[] cipherText;
            GenerateIVAndEncrypt(algorithm, new ArraySegment(plainText, offset, count), out iv, out cipherText); 
            byte[] output = DiagnosticUtility.Utility.AllocateByteArray(checked(iv.Length + cipherText.Length));
            Buffer.BlockCopy(iv, 0, output, 0, iv.Length);
            Buffer.BlockCopy(cipherText, 0, output, iv.Length, cipherText.Length);
            return output; 
        }
 
        internal static void GenerateIVAndEncrypt(SymmetricAlgorithm algorithm, ArraySegment plainText, out byte[] iv, out byte[] cipherText) 
        {
            int ivSize = algorithm.BlockSize / 8; 
            iv = new byte[ivSize];
            FillRandomBytes(iv);
            algorithm.Padding = PaddingMode.PKCS7;
            algorithm.Mode = CipherMode.CBC; 
            using (ICryptoTransform encrTransform = algorithm.CreateEncryptor(algorithm.Key, iv))
            { 
                cipherText = encrTransform.TransformFinalBlock(plainText.Array, plainText.Offset, plainText.Count); 
            }
        } 

        internal static bool IsEqual(byte[] a, byte[] b)
        {
            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; 
        }
 
        internal static bool IsSymmetricAlgorithm(string algorithm)
        {
            return GetAlgorithmType(algorithm) == CryptoAlgorithmType.Symmetric;
        } 

        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; 
            }
        } 

        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 void ValidateSymmetricKeyLength(int keyLength, SecurityAlgorithmSuite algorithmSuite) 
        {
            if (!algorithmSuite.IsSymmetricKeyLengthSupported(keyLength))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new ArgumentOutOfRangeException("algorithmSuite", 
                   SR.GetString(SR.UnsupportedKeyLength, keyLength, algorithmSuite.ToString())));
            } 
            if (keyLength % 8 != 0) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new ArgumentOutOfRangeException("algorithmSuite", 
                   SR.GetString(SR.KeyLengthMustBeMultipleOfEight, keyLength)));
            }
        }
    } 
}

// 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