예제 #1
0
        protected override void Execute(CodeActivityContext context)
        {
            try
            {
                string   inputFilePath  = InputFilePath.Get(context);
                string   outputFilePath = OutputFilePath.Get(context);
                string   key            = Key.Get(context);
                Encoding keyEncoding    = KeyEncoding.Get(context);

                if (string.IsNullOrWhiteSpace(inputFilePath))
                {
                    throw new ArgumentNullException(Resources.InputFilePathDisplayName);
                }
                if (string.IsNullOrWhiteSpace(outputFilePath))
                {
                    throw new ArgumentNullException(Resources.OutputFilePathDisplayName);
                }
                if (string.IsNullOrWhiteSpace(key))
                {
                    throw new ArgumentNullException(Resources.Key);
                }
                if (keyEncoding == null)
                {
                    throw new ArgumentNullException(Resources.Encoding);
                }
                if (!File.Exists(inputFilePath))
                {
                    throw new ArgumentException(Resources.FileDoesNotExistsException, Resources.InputFilePathDisplayName);
                }
                // Because we use File.WriteAllText below, we don't need to delete the file now.
                if (File.Exists(outputFilePath) && !Overwrite)
                {
                    throw new ArgumentException(Resources.FileAlreadyExistsException, Resources.OutputFilePathDisplayName);
                }

                byte[] encrypted = File.ReadAllBytes(inputFilePath);

                byte[] decrypted = null;
                try
                {
                    decrypted = CryptographyHelper.DecryptData(Algorithm, encrypted, keyEncoding.GetBytes(key));
                }
                catch (CryptographicException ex)
                {
                    throw new InvalidOperationException(Resources.GenericCryptographicException, ex);
                }

                // This overwrites the file if it already exists.
                File.WriteAllBytes(outputFilePath, decrypted);
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());

                if (!ContinueOnError.Get(context))
                {
                    throw;
                }
            }
        }
        /// <summary>
        /// Constructs a key based on a string <paramref name="name"/>.
        ///
        /// If the string is of the form "{16-digit hex}" or "{8-digit hex},{8-digit hex}", this will be parsed into numeric keys.
        ///
        /// If the string is an ascii string with 9 or fewer characters, it will be mapped to a key that does not collide with
        /// any other key based on such a string or based on a 32-bit value.
        ///
        /// Other string names will be rejected unless <paramref name="allowHashing"/> is specified, in which case it will be hashed to
        /// a 64-bit key value.
        /// </summary>
        public PostgresAdvisoryLockKey(string name, bool allowHashing = false)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            if (TryEncodeAscii(name, out this._key))
            {
                this._keyEncoding = KeyEncoding.Ascii;
            }
            else if (TryEncodeHashString(name, out this._key, out var hasSeparator))
            {
                this._keyEncoding = hasSeparator ? KeyEncoding.Int32Pair : KeyEncoding.Int64;
            }
            else if (allowHashing)
            {
                this._key         = HashString(name);
                this._keyEncoding = KeyEncoding.Int64;
            }
            else
            {
                throw new FormatException($"Name '{name}' could not be encoded as a {nameof(PostgresAdvisoryLockKey)}. Please specify {nameof(allowHashing)} or use one of the following formats:"
                                          + $" or (1) a 0-{MaxAsciiLength} character string using only ASCII characters"
                                          + $", (2) a {HashStringLength} character hex string, such as the result of Int64.MaxValue.ToString(\"x{HashStringLength}\")"
                                          + $", or (3) a 2-part, {SeparatedHashStringLength} character string of the form XXXXXXXX{HashStringSeparator}XXXXXXXX, where the X's are {HashPartLength} hex strings"
                                          + $" such as the result of Int32.MaxValue.ToString(\"x{HashPartLength}\")."
                                          + " Note that each unique string provided for formats 1 and 2 will map to a unique hash value, with no collisions across formats. Format 3 strings use the same key space as 2.");
            }
        }
예제 #3
0
    public static string FormatByteArray(byte[] data, KeyEncoding encoding)
    {
        switch (encoding)
        {
        case KeyEncoding.DecArray:
            return(string.Join(", ", from b in data select b));

        case KeyEncoding.HexArray:
            return("0x" + string.Join(", 0x", from b in data select b.ToString("X2")));

        case KeyEncoding.UpperHex:
            return(string.Join(string.Empty, from b in data select b.ToString("X2")));

        case KeyEncoding.LowerHex:
            return(string.Join(string.Empty, from b in data select b.ToString("x2")));

        case KeyEncoding.Base64:
            return(Convert.ToBase64String(data));

        case KeyEncoding.UrlSafeBase64:
            return(Convert.ToBase64String(data).Replace('-', '+').Replace('/', '_'));

        default:
            throw new ArgumentOutOfRangeException("encoding");
        }
    }
예제 #4
0
 public static byte[] ToBytes(this string input, KeyEncoding keyEncoding = KeyEncoding.UTF8)
 {
     return(keyEncoding switch
     {
         KeyEncoding.ASCII => Encoding.ASCII.GetBytes(input),
         KeyEncoding.Base64 => Convert.FromBase64String(input),
         _ => Encoding.UTF8.GetBytes(input),
     });
예제 #5
0
 /// <summary>
 /// Return decoded key from configured key value
 /// </summary>
 /// <returns>decoded key</returns>
 protected byte[] DecodeKey()
 {
     if (!KeyEncoding.Equals("base64", StringComparison.CurrentCultureIgnoreCase))
     {
         return(Encoding.UTF8.GetBytes(KeyValue));
     }
     else
     {
         return(Convert.FromBase64String(KeyValue));
     }
 }
예제 #6
0
    public static string GenerateKey(int length, KeyEncoding encoding)
    {
        // Validate arguments
        if (length < 1)
        {
            throw new ArgumentOutOfRangeException("length");
        }

        // Get random bytes
        var chaos = new byte[length];

        using (var rng = new RNGCryptoServiceProvider()) {
            rng.GetBytes(chaos);
        }

        // Format random bytes to various formats
        return(FormatByteArray(chaos, encoding));
    }
예제 #7
0
        /// <summary>
        /// Parses a string into the key
        /// </summary>
        /// <param name="keyString">The string to parse</param>
        /// <returns>Whether or not the parsing was succesfull</returns>
        private bool ParseKey(String keyString)
        {
            KeyEncoding encoding = KeyEncoding.UNKNOWN;

            String nums    = "0123456789";
            String hexNums = "abcdefABCDEF";

            //Establish which format to parse the string as
            foreach (char c in keyString.ToCharArray())
            {
                switch (encoding)
                {
                case KeyEncoding.UNKNOWN:
                    if (nums.Contains(c))
                    {
                        encoding = KeyEncoding.DECIMAL;
                    }
                    else if (hexNums.Contains(c))
                    {
                        encoding = KeyEncoding.HEX;
                    }
                    else if ((short)c <= 255)
                    {
                        encoding = KeyEncoding.ASCII;
                    }
                    else
                    {
                        encoding = KeyEncoding.UNICODE;
                    }
                    break;

                case KeyEncoding.DECIMAL:
                    if (nums.Contains(c))
                    {
                        continue;
                    }
                    else if (hexNums.Contains(c))
                    {
                        encoding = KeyEncoding.HEX;
                    }
                    else if ((short)c <= 255)
                    {
                        encoding = KeyEncoding.ASCII;
                    }
                    else
                    {
                        encoding = KeyEncoding.UNICODE;
                    }
                    break;

                case KeyEncoding.HEX:
                    if (nums.Contains(c) || hexNums.Contains(c))
                    {
                        continue;
                    }
                    else if ((short)c <= 255)
                    {
                        encoding = KeyEncoding.ASCII;
                    }
                    else
                    {
                        encoding = KeyEncoding.UNICODE;
                    }
                    break;

                case KeyEncoding.ASCII:
                    if ((short)c <= 255)
                    {
                        continue;
                    }
                    else
                    {
                        encoding = KeyEncoding.UNICODE;
                    }
                    break;
                }
            }

            switch (encoding)
            {
            //For decimal, just parse. Easy Peasy
            case KeyEncoding.DECIMAL:
                try
                {
                    key = UInt128.Parse(keyString);
                    return(true);
                } catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    return(false);
                }

            //For hex first add 00 at the start of the string to ensure good parsing, and then parse
            case KeyEncoding.HEX:
                try
                {
                    UInt128.TryParse("00" + keyString, System.Globalization.NumberStyles.HexNumber, System.Globalization.NumberFormatInfo.CurrentInfo, out this.key);
                    return(true);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    return(false);
                }

            //For ASCII take the low byte of the characters
            case KeyEncoding.ASCII:
                if (keyString.Length > BlockSize)
                {
                    Console.WriteLine("Key too long, maximum of 16 ASCII characters allowed");
                    return(false);
                }

                key = 0;

                for (int i = 0; i < keyString.Length; i++)
                {
                    key |= (UInt128)((byte)keyString.ToCharArray()[i] << (i * 8));
                }

                return(true);

            //For unicode take both bytes of the characters
            case KeyEncoding.UNICODE:
                if (keyString.Length * 2 > BlockSize)
                {
                    Console.WriteLine("Key too long, maximum of 8 Unicode characters allowed");
                    return(false);
                }

                key = 0;

                for (int i = 0; i < keyString.Length; i++)
                {
                    key |= (UInt128)((short)(keyString.ToCharArray()[i]) << (i * 16));
                }

                return(true);
            }

            return(false);
        }
 /// <summary>
 /// Constructs a key from a pair of 32-bit values. This is a separate key space
 /// than <see cref="PostgresAdvisoryLockKey(long)"/>.
 /// </summary>
 public PostgresAdvisoryLockKey(int key1, int key2)
 {
     this._key         = CombineKeys(key1, key2);
     this._keyEncoding = KeyEncoding.Int32Pair;
 }
 /// <summary>
 /// Constructs a key from a single 64-bit value. This is a separate key space
 /// than <see cref="PostgresAdvisoryLockKey(int, int)"/>.
 /// </summary>
 public PostgresAdvisoryLockKey(long key)
 {
     this._key         = key;
     this._keyEncoding = KeyEncoding.Int64;
 }