Пример #1
0
        private static string Decrypt_Private(string encryptedString, byte[] passwordBytes, bool useBase36)
        {
            if (string.IsNullOrEmpty(encryptedString))
            {
                throw new InvalidOperationException("Invalid encryptedString");
            }

            if (encryptedString.Length < 10)
            {
                throw new InvalidOperationException("Invalid encryptedString");
            }

            byte[] encryptedStringAsBytes;
            byte   version;

            if (useBase36)
            {
                var encryptedStringUpper = encryptedString.ToUpper(); // always upper on base36
                encryptedStringAsBytes = Base36.Base36StringToByteArray(encryptedString);
            }
            else
            {
                encryptedStringAsBytes = Convert.FromBase64String(encryptedString);
            }

            // we can implement new versions down the line
            version = encryptedStringAsBytes[0];

            // only v1 is implemented for now
            if (version == 1)
            {
                var decryptedBytes = Decrypt_Private_v1(encryptedStringAsBytes, passwordBytes);
                // use UTF8 string
                string plainText = Encoding.UTF8.GetString(decryptedBytes);

                // Return decrypted string.
                return(plainText);
            }

            // if version is not implemented, throw ex
            throw new NotImplementedException(string.Format("Version '{0} not impleneted.", version.ToString()));
        }
        /// <summary>
        /// Decrypts specified ciphertext using Rijndael symmetric key algorithm.
        /// </summary>
        /// <param name="cipherText">
        /// Base64-formatted ciphertext value.
        /// </param>
        /// <param name="passPhrase">
        /// Passphrase from which a pseudo-random password will be derived. The
        /// derived password will be used to generate the encryption key.
        /// Passphrase can be any string. In this example we assume that this
        /// passphrase is an ASCII string.
        /// </param>
        /// <returns>
        /// Decrypted string value.
        /// </returns>
        /// <remarks>
        /// Most of the logic in this function is similar to the Encrypt
        /// logic. In order for decryption to work, all parameters of this function
        /// - except cipherText value - must match the corresponding parameters of
        /// the Encrypt function which was called to generate the
        /// ciphertext.
        /// </remarks>
        private static string Decrypt_Private(string cipherText, string passPhrase, bool useBase36)
        {
            // Convert strings defining encryption key characteristics into byte
            // arrays. Let us assume that strings only contain ASCII codes.
            // If strings include Unicode characters, use Unicode, UTF7, or UTF8
            // encoding.

            if (string.IsNullOrEmpty(cipherText))
            {
                throw new InvalidOperationException("Invalid cipherText");
            }

            if (cipherText.Length < 23)
            {
                throw new InvalidOperationException("Invalid cipherText");
            }

            string strIv = cipherText.Substring(0, 16);

            string strSalt = cipherText.Substring(16, 8);

            string strCipher = cipherText.Substring(24);


            byte[] initVectorBytes = Encoding.ASCII.GetBytes(strIv);
            byte[] saltValueBytes  = Encoding.ASCII.GetBytes(strSalt);

            // Convert our ciphertext into a byte array.
            byte[] cipherTextBytes;

            if (useBase36)
            {
                strCipher       = strCipher.ToUpper();
                cipherTextBytes = Base36.Base36StringToByteArray(strCipher);
            }
            else
            {
                cipherTextBytes = Convert.FromBase64String(strCipher);
            }

            // First, we must create a password, from which the key will be
            // derived. This password will be generated from the specified
            // passphrase and salt value. The password will be created using
            // the specified hash algorithm. Password creation can be done in
            // several iterations.
            //Dim password As New PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations)

            Rfc2898DeriveBytes pw = new Rfc2898DeriveBytes(passPhrase, saltValueBytes, 2);

            // Use the password to generate pseudo-random bytes for the encryption
            // key. Specify the size of the key in bytes (instead of bits).
            byte[] keyBytes = pw.GetBytes(256 / 8);

            // Create uninitialized Rijndael encryption object.
            RijndaelManaged symmetricKey = new RijndaelManaged();

            // It is reasonable to set encryption mode to Cipher Block Chaining
            // (CBC). Use default options for other symmetric key parameters.
            symmetricKey.Mode = CipherMode.CBC;

            // Generate decryptor from the existing key bytes and initialization
            // vector. Key size will be defined based on the number of the key
            // bytes.
            ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);

            // Define memory stream which will be used to hold encrypted data.
            MemoryStream memoryStream = new MemoryStream(cipherTextBytes);

            // Define cryptographic stream (always use Read mode for encryption).
            CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);

            // Since at this point we don't know what the size of decrypted data
            // will be, allocate the buffer long enough to hold ciphertext;
            // plaintext is never longer than ciphertext.
            byte[] plainTextBytes = new byte[cipherTextBytes.Length];

            // Start decrypting.
            int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);

            // Close both streams.
            memoryStream.Close();
            cryptoStream.Close();

            // Convert decrypted data into a string.
            // Let us assume that the original plaintext string was UTF8-encoded.
            string plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);

            // Return decrypted string.
            return(plainText);
        }