Пример #1
0
        /// <summary>
        /// Decrypt string data with a supported cipher, authenticate the cipher using a supported digest type, deviate the cipher password with a supported divination type, and, finally pad a cipher using a supported padding type.
        /// </summary>
        /// <param name="data">String data.</param>
        /// <param name="password">Cipher password. Will be deviated using the supplied divination type.</param>
        /// <param name="salt">Cipher salt to be used, should be proper format for the cipher type. (Note: Normally 8, or, 14 bytes)</param>
        /// <param name="secondaryVerifier">Secondary data you wish to use to validate the cipher. This is a secondary validation check. The cipher binary is already validated. (Note: This will increase the size of the cipher)</param>
        /// <returns>Byte data</returns>
        public static string FromEncryptionAtRest(this string data, string password, byte[] salt, string secondaryVerifier = null)
        {
            var iv = new UTF8Encoding().GetBytes(data.Substring(0, 16));
            var key = password.ToHash(salt);

            var suspectedInputVerifier = data.Substring(data.Length - 32, data.Length);
            var input = new UTF8Encoding().GetBytes(data.Substring(16, data.Length - 32));
            var expectedInputVerifier = input.ToHmac(key.Data, salt);
            if (!suspectedInputVerifier.Equals(expectedInputVerifier.Data))
            {
                return string.Empty;
            }

            var cipher = CipherUtilities.GetCipher("AES/CBC/PKCS7");
            cipher.Init(false, new ParametersWithIV(new KeyParameter(key.Data), iv));
            var outputData = cipher.DoFinal(input);
            cipher.Reset();

            var output = new UTF8Encoding().GetString(outputData);
            if (!string.IsNullOrEmpty(secondaryVerifier))
            {
                var expectedVerifier = secondaryVerifier.ToHmac(key.Data, salt).Data.ToHex();
                var suspectedVerifier = output.Substring(output.Length - 64, 64);
                if (!expectedVerifier.SequenceEqual(suspectedVerifier))
                {
                    return string.Empty;
                }

                output = output.Substring(0, output.Length - 64);
            }

            return output;
        }