Ejemplo n.º 1
0
        /// <summary>
        /// Returns <c>true</c> if the key string passed is a valid XML key
        /// and is NOT a key container name.
        /// </summary>
        /// <param name="algorithm">The asymmetric algorithm.</param>
        /// <param name="key">The key string to be tested.</param>
        /// <returns><c>true</c> if the key is a valid XML key.</returns>
        /// <remarks>
        /// The current implementation supports only the "RSA" provider.
        /// </remarks>
        public static bool IsXmlKey(string algorithm, string key)
        {
            AsymmetricAlgorithm asymmetric = null;

            try
            {
                if (ParseKeyContainer(key) != null)
                {
                    return(false);
                }

                asymmetric = EncryptionConfig.CreateAsymmetric(algorithm, 0);
                asymmetric.FromXmlString(key);

                return(true);
            }
            catch
            {
                return(false);
            }
            finally
            {
                if (asymmetric != null)
                {
                    asymmetric.Clear();
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Generates a symmetric encryption key of the given size and algorithm
        /// from a shared secret and optional cryptographic salt.
        /// </summary>
        /// <param name="algorithm">The algorithm name.</param>
        /// <param name="keySize">The desired key size in bits.</param>
        /// <param name="secret">The shared secret as a byta array.</param>
        /// <param name="salt">An optional array of at least 8 salt bytes or <c>null</c>.</param>
        /// <returns>The <see cref="SymmetricKey" />.</returns>
        /// <exception cref="ArgumentException">Thrown if <paramref name="salt" /> is not <c>null</c> and contains less than 8 bytes of salt.</exception>
        /// <remarks>
        /// <para>
        /// This method is useful for situations where two endpoints wish to communicate
        /// securely when they each know a shared secret such as a password or the hash
        /// of a password.
        /// </para>
        /// <note>
        /// Endpoints that wish to generate a key from a password string should use
        /// a text <see cref="Encoding"/> to convert the string into bytes.  Note also
        /// that the endpoints will need to agree on the same salt bytes to make sure
        /// that the same key is generated on both ends.
        /// </note>
        /// <note>
        /// If <paramref name="salt" /> is passed as <c>null</c> then the class will use
        /// 8 bytes of built-in salt instead.
        /// </note>
        /// </remarks>
        public static SymmetricKey GenerateSymmetricKeyFromSecret(string algorithm, int keySize, byte[] secret, byte[] salt)
        {
            if (salt != null && salt.Length < 8)
            {
                throw new ArgumentException("At least eight bytes of cryptographic salt is required.", "salt");
            }

            if (String.Compare(algorithm, CryptoAlgorithm.PlainText, StringComparison.OrdinalIgnoreCase) == 0)
            {
                return(new SymmetricKey(CryptoAlgorithm.PlainText, new byte[keySize], new byte[0]));
            }

            SymmetricAlgorithm symmetric = EncryptionConfig.CreateSymmetric(algorithm);
            Rfc2898DeriveBytes key;

            if (salt == null)
            {
                salt = new byte[] { 0x89, 0x55, 0x71, 0xEA, 0xD3, 0x16, 0x87, 0xFF }
            }
            ;

            key = new Rfc2898DeriveBytes(secret, salt, 3);

            try
            {
                symmetric.KeySize = keySize;

                return(new SymmetricKey(algorithm, key.GetBytes(symmetric.KeySize / 8), key.GetBytes(symmetric.BlockSize / 8)));
            }
            finally
            {
                symmetric.Clear();
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Generates a symmetric encryption key and initialization vector
        /// of a given size for the specified encryption algorithm.
        /// </summary>
        /// <param name="algorithm">The algorithm name.</param>
        /// <param name="keySize">The desired key size in bits.</param>
        /// <param name="key">Returns as the generated key.</param>
        /// <param name="IV">Returns as the generated initialization vector.</param>
        /// <remarks>
        /// The current supported cross platform encryption algorithms
        /// are: "DES", "RC2", "TripleDES", and "AES" (Rijndael).
        /// </remarks>
        public static void GenerateSymmetricKey(string algorithm, int keySize, out byte[] key, out byte[] IV)
        {
            if (String.Compare(algorithm, CryptoAlgorithm.PlainText, StringComparison.OrdinalIgnoreCase) == 0)
            {
                key = new byte[keySize];
                IV  = new byte[0];
                return;
            }

            var symmetric = EncryptionConfig.CreateSymmetric(algorithm);

            try
            {
                symmetric.KeySize = keySize;
                symmetric.GenerateKey();
                symmetric.GenerateIV();

                key = symmetric.Key;
                IV  = symmetric.IV;
            }
            finally
            {
                symmetric.Clear();
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Returns the valid key sizes in bits for the specified encryption algorithm.
        /// </summary>
        /// <param name="algorithm">The algorithm name.</param>
        /// <returns>The array of possible key sizes in bits sorted in decending order.</returns>
        public static int[] GetValidKeySizes(string algorithm)
        {
            EncryptionConfig config = null;

            for (int i = 0; i < platformSymmetric.Length; i++)
            {
                if (String.Compare(algorithm, platformSymmetric[i].Algorithm, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    config = platformSymmetric[i];
                    break;
                }
            }

            for (int i = 0; i < platformAsymmetric.Length; i++)
            {
                if (String.Compare(algorithm, platformAsymmetric[i].Algorithm, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    config = platformAsymmetric[i];
                    break;
                }
            }

            if (config == null)
            {
                throw new ArgumentException(Crypto.UnknownAlgorithm);
            }

            return(config.KeySizes);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Initializes the decryptor to use the specified encryption algorithm,
        /// key, and initialization vector.
        /// </summary>
        /// <param name="algorithm">The symmetric algorithm name.</param>
        /// <param name="key">The encryption key.</param>
        /// <param name="IV">The initialization vector.</param>
        public BlockDecryptor(string algorithm, byte[] key, byte[] IV)
        {
            this.algorithm = algorithm;
            this.key       = key;
            this.IV        = IV;

            this.provider     = EncryptionConfig.CreateSymmetric(algorithm);
            this.provider.Key = key;
            this.provider.IV  = IV;

            this.decryptor = null;
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Generates an asymmetric private key and returns the result as XML.
        /// </summary>
        /// <param name="algorithm">The asymmetric algorithm name.</param>
        /// <param name="keySize">The key size in bits.</param>
        /// <returns>The private key encoded as XML.</returns>
        /// <remarks>
        /// The current implementation supports only the "RSA" provider.
        /// </remarks>
        public static string CreatePrivateKey(string algorithm, int keySize)
        {
            var asymmetric = EncryptionConfig.CreateAsymmetric(algorithm, keySize);

            try
            {
                return(asymmetric.ToXmlString(true));
            }
            finally
            {
                asymmetric.Clear();
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Returns the public key for a private key.
        /// </summary>
        /// <param name="algorithm">The asymmetric algorithm.</param>
        /// <param name="privateKeyXml">The private key encoded as XML.</param>
        /// <returns>The public key encoded as XML.</returns>
        /// <remarks>
        /// The current implementation supports only the "RSA" provider.
        /// </remarks>
        public static string GetPublicKey(string algorithm, string privateKeyXml)
        {
            var asymmetric = EncryptionConfig.CreateAsymmetric(algorithm, 0);

            try
            {
                asymmetric.FromXmlString(privateKeyXml);
                return(asymmetric.ToXmlString(false));
            }
            finally
            {
                asymmetric.Clear();
            }
        }
Ejemplo n.º 8
0
        static EncryptionConfig()
        {
            platformSymmetric = new EncryptionConfig[]  {
                EncryptionConfig.Parse("PlainText:0"),
                EncryptionConfig.Parse("RC2:128,120,112,104,96,88,80,72,64,56,48,40"),
                EncryptionConfig.Parse("TripleDES:192,128"),
                EncryptionConfig.Parse("DES:64"),
                EncryptionConfig.Parse("AES:256,192,128"),
            };

            platformAsymmetric = new EncryptionConfig[] {
                EncryptionConfig.Parse("RSA:4096,2048,1024,512")
            };
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Returns the largest valid key size (expressed in bits) for the
        /// algorithm specified.
        /// </summary>
        /// <param name="algorithm">The algorithm name.</param>
        /// <returns>The maximum key size in bits.</returns>
        public static int MaxAlgorithmKeySize(string algorithm)
        {
            EncryptionConfig config = null;
            int maxKey = 0;

            for (int i = 0; i < platformSymmetric.Length; i++)
            {
                if (String.Compare(algorithm, platformSymmetric[i].Algorithm, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    config = platformSymmetric[i];
                    break;
                }
            }

            for (int i = 0; i < platformAsymmetric.Length; i++)
            {
                if (String.Compare(algorithm, platformAsymmetric[i].Algorithm, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    config = platformAsymmetric[i];
                    break;
                }
            }

            if (config == null)
            {
                throw new ArgumentException(Crypto.UnknownAlgorithm);
            }

            for (int i = 0; i < config.KeySizes.Length; i++)
            {
                if (config.KeySizes[i] > maxKey)
                {
                    maxKey = config.KeySizes[i];
                }
            }

            Assertion.Test(maxKey > 0);
            return(maxKey);
        }