Пример #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="RijndaelEncryptor"/> class using the user supplied key and initial vector arrays.
        /// NOTE: these arrays will be validated for use with the <see cref="RijndaelManaged"/> cypher.
        /// </summary>
        /// <param name="encryptedKey"></param>
        /// <param name="encryptedIV"></param>
        public RijndaelEncryptor(byte[] encryptedKey, byte[] encryptedIV)
        {
            if (encryptedKey == null)
            {
                throw new ArgumentNullException("encryptedKey");
            }
            if (encryptedIV == null)
            {
                throw new ArgumentNullException("encryptedIV");
            }

            //Verify encrypted key length is valid for this cryptor algo.
            int keylen = encryptedKey.Length << 3;

            if (!_crypt.ValidKeySize(keylen))
            {
                string errmsg = "Encryption key length(" + keylen.ToString() + ") is not for this algorithm:" + _crypt.GetType().Name;
                throw new ApplicationException(errmsg);
            }

            //Verify encrypted iv length is valid for this cryptor algo.
            int len = encryptedIV.Length << 3;

            if (len != _crypt.BlockSize)
            {
                string errmsg = "Encryption key length(" + len.ToString() + ") is not for this algorithm:" + _crypt.GetType().Name;
                throw new ApplicationException(errmsg);
            }

            EncryptKey = encryptedKey;
            EncryptIV  = encryptedIV;
        }
Пример #2
0
 static bool IsValidKey(byte[] key)
 {
     using (var rijndael = new RijndaelManaged())
     {
         var bitLength = key.Length * 8;
         return(rijndael.ValidKeySize(bitLength));
     }
 }
        static bool IsValidKey(byte[] key)
        {
            using (var rijndael = new RijndaelManaged())
            {
                var bitLength = key.Length * 8;

                var maxValidKeyBitLength = rijndael.LegalKeySizes.Max(keyLength => keyLength.MaxSize);
                if (bitLength < maxValidKeyBitLength)
                {
                    Log.WarnFormat("Encryption key is {0} bits which is less than the maximum allowed {1} bits. Consider using a {1}-bit encryption key to obtain the maximum cipher strength", bitLength, maxValidKeyBitLength);
                }

                return(rijndael.ValidKeySize(bitLength));
            }
        }
Пример #4
0
 /// <summary>
 /// Given an open registry key and a site key value, read the site parameters from
 /// the registry and return a SiteParameters object.
 /// </summary>
 /// <param name="registryKey">An open registry key</param>
 /// <param name="siteKey">A site key string</param>
 /// <returns>A SiteParameters object, or null on failure</returns>
 public static SiteParameters ReadFromRegistry(RegistryKey registryKey, string siteKey)
 {
     // Asbestos underpants:
     try
     {
         // This only works if the registry key is open and the site key is
         // something meaningful:
         if (registryKey != null && !String.IsNullOrEmpty(siteKey))
         {
             // Look for the site key value in the registry key and convert it from
             // Base64 to a byte array:
             byte[] encryptedParams = (byte[])registryKey.GetValue(siteKey);
             // Set up our decryption engine.  Create the Rijndael object, its
             // encryption key, and its initialization vector.
             RijndaelManaged rijndael = new RijndaelManaged();
             if (rijndael.ValidKeySize(256))
             {
                 rijndael.KeySize = 256;
             }
             rijndael.Padding = PaddingMode.PKCS7;
             byte[] cryptKey = GenerateEncryptionKey(siteKey);
             byte[] iv       = GenerateIV(rijndael.BlockSize / 8, siteKey);
             // Decrypt the raw bytes read from the registry:
             ICryptoTransform decryptor      = rijndael.CreateDecryptor(cryptKey, iv);
             MemoryStream     ms             = new MemoryStream(encryptedParams);
             CryptoStream     cs             = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
             byte[]           decryptedBytes = new byte[encryptedParams.Length];
             cs.Read(decryptedBytes, 0, decryptedBytes.Length);
             cs.Close();
             ms.Close();
             // Reset the memory stream to read the raw bytes and use a binary
             // formatter to deserialize the object:
             ms = new MemoryStream(decryptedBytes);
             BinaryFormatter bf = new BinaryFormatter();
             SiteParameters  sp = (SiteParameters)bf.Deserialize(ms);
             return(sp);
         }
         // If the registry key wasn't open or the site key wasn't meaningful, there's
         // nothing to do:
         else
         {
             return(null);
         }
     }
     // If anything blows up, don't return anything we can use:
     catch { return(null); }
 }
Пример #5
0
 /// <summary>
 /// Given an open registry key, save this set of site parameters as a subkey under
 /// that registry, encrypting the data as we go.
 /// </summary>
 /// <param name="registryKey">The parent registry key</param>
 /// <returns>True for success, false for failure</returns>
 public bool SaveToRegistry(RegistryKey registryKey)
 {
     // This only makes sense if the registry key exists, i.e. it is open:
     if (registryKey != null)
     {
         // Asbestos underpants:
         try
         {
             // Serialize the parameters binary data:
             BinaryFormatter bf = new BinaryFormatter();
             MemoryStream    ms = new MemoryStream();
             bf.Serialize(ms, this);
             ms.Close();
             byte[] serializedParams = ms.ToArray();
             // Generate the Rijndael object, encryption key and initialization vector:
             RijndaelManaged rijndael = new RijndaelManaged();
             if (rijndael.ValidKeySize(256))
             {
                 rijndael.KeySize = 256;
             }
             rijndael.Padding = PaddingMode.PKCS7;
             byte[] cryptKey = GenerateEncryptionKey(Key);
             byte[] iv       = GenerateIV(rijndael.BlockSize / 8, Key);
             // Encrypt the site parameters:
             ICryptoTransform encryptor = rijndael.CreateEncryptor(cryptKey, iv);
             ms = new MemoryStream();
             CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
             cs.Write(serializedParams, 0, serializedParams.Length);
             cs.FlushFinalBlock();
             cs.Close();
             ms.Close();
             // Now convert the data to Base64 and save it to the registry using the
             // generated key
             registryKey.SetValue(Key, ms.ToArray(), RegistryValueKind.Binary);
             return(true);
         }
         // If anything failed, let the user know:
         catch { return(false); }
     }
     // If the registry key wasn't open, there's no use continuing:
     else
     {
         return(false);
     }
 }
Пример #6
0
        public static bool ValidateKeySize(EncryptionAlgorithm algID, int Lenght)
        {
            switch (algID)
            {
            case EncryptionAlgorithm.DES:
                DES des = new DESCryptoServiceProvider();
                return(des.ValidKeySize(Lenght));

            case EncryptionAlgorithm.Rc2:
                RC2 rc = new RC2CryptoServiceProvider();
                return(rc.ValidKeySize(Lenght));

            case EncryptionAlgorithm.Rijndael:
                Rijndael rj = new RijndaelManaged();
                return(rj.ValidKeySize(Lenght));

            case EncryptionAlgorithm.TripleDes:
                TripleDES tDes = new TripleDESCryptoServiceProvider();
                return(tDes.ValidKeySize(Lenght));

            default:
                throw new CryptographicException("Algorithm " + algID + " Not Supported!");
            }
        }
Пример #7
0
        /// <summary>
        /// Encrypt the specified data and write it out to the specified file name
        /// </summary>
        /// <param name="filename">A string containing the path to the file to create.  If the file
        /// already exists, it will be overwritten.</param>
        /// <param name="data">A byte array containing the data to encrypt</param>
        /// <param name="passphrase">A string containing the passphrase which will encrypt
        /// the data</param>
        /// <param name="iv">A byte array containing the initialization vector (IV) which will
        /// encrypt the data</param>
        public static void Write(string filename, byte[] data, string passphrase, byte[] iv)
        {
            try
            {
                // Create the output file stream.  It may seem a bit odd to do this first, before we
                // have any data to write, but this will ensure we throw any file access exceptions
                // before we get to the expensive compression/encryption stuff.
                FileStream output = new FileStream(filename, FileMode.Create);

                // The first thing we have to do is append the header to the data.  If we don't, we
                // can't guarantee later that the passphrase used to decrypt the data is the same as
                // the passphrase used to encrypt it.  So convert the header string to bytes and stick
                // those bytes to the beginning of the data.
                byte[] headerBytes    = utf8.GetBytes(header);
                byte[] dataWithHeader = new byte[data.Length + headerBytes.Length];
                Array.Copy(headerBytes, dataWithHeader, headerBytes.Length);
                Array.Copy(data, 0, dataWithHeader, headerBytes.Length, data.Length);

                // First we want to compress the data.  Create a memory stream to write to, then wrap
                // a GZipStream around that.  Write the data bytes to the compressed stream.  Make
                // sure to close the streams before doing anything with the data itself.
                MemoryStream compressedStream = new MemoryStream();
                GZipStream   zipper           = new GZipStream(compressedStream, CompressionMode.Compress);
                zipper.Write(dataWithHeader, 0, dataWithHeader.Length);
                zipper.Close();
                compressedStream.Close();

                // Now we need to get the compressed data back out and into a byte array we can feed
                // to the encryptor:
                byte[] compressedData = compressedStream.ToArray();

                // Create a new Rijndael instance and set its key size to 256-bits, the highest
                // we can go.  Also set our padding mode to PKCS #7, which will make it easier for
                // us to tell where the data ends and the padding begins when we decrypt this later.
                // Finally, create a crypto transform using that instance and feed it the hashed
                // password and derived IV.
                if (rijndael.ValidKeySize(256))
                {
                    rijndael.KeySize = 256;
                }
                rijndael.Padding = PaddingMode.PKCS7;
                ICryptoTransform encryptor =
                    rijndael.CreateEncryptor(HashPassphrase(passphrase), iv);

                // Next, encrypt the data.  We'll reuse the memory stream we had before and create a
                // crypto stream to wrap around it.  Write the compressed data into the encryption
                // stream.  Again, close the streams before reading the data; this is important here
                // so the padding gets done correctly.
                compressedStream = new MemoryStream();
                CryptoStream cs = new CryptoStream(compressedStream, encryptor,
                                                   CryptoStreamMode.Write);
                cs.Write(compressedData, 0, compressedData.Length);
                cs.FlushFinalBlock();
                cs.Close();
                compressedStream.Close();

                // Get the newly encrypted, compressed data back into byte array form:
                byte[] encryptedData = compressedStream.ToArray();

                // Now that we have the encrypted data, write it to the file and close up shop:
                output.Write(encryptedData, 0, encryptedData.Length);
                output.Flush();
                output.Close();
            }
            #region Catching Exceptions
            catch (UnauthorizedAccessException)
            {
                throw new SecureFileException("You do not have the necessary permissions to access " +
                                              "the file " + filename);
            }
            catch (System.Security.SecurityException)
            {
                throw new SecureFileException("You do not have the necessary permissions to access " +
                                              "the file " + filename);
            }
            catch (ArgumentException)
            {
                throw new SecureFileException("The specified file path was empty or contained " +
                                              "invalid characters");
            }
            catch (IOException)
            {
                throw new SecureFileException("An I/O error occurred while trying to write to " +
                                              "the file " + filename);
            }
            // A generic catch-all, just in case:
            catch (Exception ex)
            {
                throw new SecureFileException(ex.Message);
            }
            #endregion
        }