예제 #1
0
        /// <inheritdoc />
        public string Decrypt(string input, out bool isLatestKey)
        {
            isLatestKey = false;

            if (string.IsNullOrEmpty(input))
            {
                return(input);
            }

            byte[] initializationVector = new byte[16];

            // Note: Each symbol in a Base32 string is 5 bits.
            byte[] buffer = new byte[input.Length * 5 / 8];

            if (Base32EncoderDecoder.TryBase32Decode(input, buffer))
            {
                using (MemoryStream memoryStream = new MemoryStream(buffer))
                    // Retrieve the IV from the encrypted string.
                    memoryStream.Read(initializationVector, 0, initializationVector.Length);

                // Need just the text to decrypt now, ignoring the IV.
                byte[] cipherText = buffer.Skip(initializationVector.Length).ToArray();

                string decryptedString    = null;
                bool   decryptionKeyFound = false;

                // Try to find the key used in the encryption.
                foreach (Key key in _aesEncryptionKeys)
                {
                    if (TryDecryptStringFromBytes(
                            cipherText,
                            ConvertHexStringToByteArray(key.Value),
                            initializationVector,
                            out decryptedString))
                    {
                        decryptionKeyFound = true;

                        Debug.Assert(_aesEncryptionKeys[0] != null);
                        if (key.Value == _aesEncryptionKeys[0].Value)
                        {
                            isLatestKey = true;
                        }

                        break;
                    }
                }

                if (!decryptionKeyFound)
                {
                    throw new CryptographicException(Resources.AESCryptographer_Decrypt_DecryptFailed_KeyNotFound);
                }

                return(decryptedString);
            }

            // If we get here, decryption failed.
            throw new CryptographicException(
                      // ReSharper disable once AssignNullToNotNullAttribute
                      string.Format(Resources.AESCryptographer_Decrypt_DecryptFailed_InputNotBase32String, input));
        }
예제 #2
0
        /// <inheritdoc />
        public string Encrypt(string input)
        {
            if (string.IsNullOrEmpty(input))
            {
                return(input);
            }

            using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())
            {
                Key  encryptionKey = null;
                bool addNewKey     = true;

                if (_aesEncryptionKeys.Count > 0)
                {
                    // Check if there is any non-Expired keys to use.
                    bool nonExpiredKeysFound = _aesEncryptionKeys.Count(k => k.Expiry > DateTime.Now) > 0;

                    if (nonExpiredKeysFound)
                    {
                        encryptionKey = _aesEncryptionKeys[0];
                        addNewKey     = false;
                    }
                }

                if (addNewKey)
                {
                    const int defaultKeyLifeInDays = 7;

                    // Use the key automatically generated by the AesCryptoServiceProvider.
                    // Store it as a hex string.
                    string value = string.Concat(aes.Key.Select(b => b.ToString("x2")));

                    // For the expiry, use the number of days specified in the KeyLifeInDays property.
                    DateTime expiry = DateTime.Now.Add(
                        TimeSpan.FromDays(_provider != null ? _provider.KeyLifeInDays : defaultKeyLifeInDays));

                    encryptionKey = new Key(value, expiry);

                    _aesEncryptionKeys.Add(encryptionKey);
                    _aesEncryptionKeys = _aesEncryptionKeys.OrderByDescending(k => k.Expiry).ToList();

                    _provider?.AddKey(encryptionKey);
                }

                Debug.Assert(encryptionKey != null);
                byte[] encrypted = EncryptStringToBytes(input, ConvertHexStringToByteArray(encryptionKey.Value), aes.IV);

                return(Base32EncoderDecoder.Base32Encode(encrypted));
            }
        }