예제 #1
0
        /// <summary>Derives a secret key of any size from a password and a salt.</summary>
        /// <param name="password">The password.</param>
        /// <param name="salt">The salt.</param>
        /// <param name="limit">The limit for computation.</param>
        /// <param name="outputLength">The length of the computed output array.</param>
        /// <param name="alg">Argon Algorithm</param>
        /// <returns>Returns a byte array of the given size.</returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <exception cref="SaltOutOfRangeException"></exception>
        /// <exception cref="OutOfMemoryException"></exception>
        public static byte[] ArgonHashBinary(byte[] password, byte[] salt, StrengthArgon limit = StrengthArgon.Interactive, long outputLength = ARGON_SALTBYTES,
                                             ArgonAlgorithm alg = ArgonAlgorithm.Argon_2I13)
        {
            int  memLimit;
            long opsLimit;

            switch (limit)
            {
            case StrengthArgon.Interactive:
                opsLimit = ARGON_OPSLIMIT_INTERACTIVE;
                memLimit = ARGON_MEMLIMIT_INTERACTIVE;
                break;

            case StrengthArgon.Moderate:
                opsLimit = ARGON_OPSLIMIT_MODERATE;
                memLimit = ARGON_MEMLIMIT_MODERATE;
                break;

            case StrengthArgon.Sensitive:
                opsLimit = ARGON_OPSLIMIT_SENSITIVE;
                memLimit = ARGON_MEMLIMIT_SENSITIVE;
                break;

            default:
                opsLimit = ARGON_OPSLIMIT_INTERACTIVE;
                memLimit = ARGON_MEMLIMIT_INTERACTIVE;
                break;
            }

            return(ArgonHashBinary(password, salt, opsLimit, memLimit, outputLength, alg));
        }
예제 #2
0
        /// <summary>Derives a secret key of any size from a password and a salt.</summary>
        /// <param name="password">The password.</param>
        /// <param name="salt">The salt.</param>
        /// <param name="limit">The limit for computation.</param>
        /// <param name="outputLength">The length of the computed output array.</param>
        /// <param name="alg">Argon Algorithm</param>
        /// <returns>Returns a byte array of the given size.</returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <exception cref="SaltOutOfRangeException"></exception>
        /// <exception cref="OutOfMemoryException"></exception>
        public static byte[] ArgonHashBinary(byte[] password, byte[] salt, StrengthArgon limit = StrengthArgon.Interactive, long outputLength = ARGON_SALTBYTES,
                                             ArgonAlgorithm alg = ArgonAlgorithm.Argon_2I13)
        {
            var(opsLimit, memLimit) = GetArgonOpsAndMemoryLimit(limit);

            return(ArgonHashBinary(password, salt, opsLimit, memLimit, outputLength, alg));
        }
예제 #3
0
        /// <summary>
        /// Derives a secret key of any size from a password and a salt.
        /// </summary>
        /// <param name="password">The password.</param>
        /// <param name="salt">The salt.</param>
        /// <param name="opsLimit">Represents a maximum amount of computations to perform.</param>
        /// <param name="memLimit">Is the maximum amount of RAM that the function will use, in bytes.</param>
        /// <param name="outputLength">The length of the computed output array.</param>
        /// <param name="alg">Argon Algorithm</param>
        /// <returns>Returns a byte array of the given size.</returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <exception cref="SaltOutOfRangeException"></exception>
        /// <exception cref="OutOfMemoryException"></exception>
        public static byte[] ArgonHashBinary(byte[] password, byte[] salt, long opsLimit, int memLimit, long outputLength = ARGON_SALTBYTES,
                                             ArgonAlgorithm alg = ArgonAlgorithm.Argon_2I13)
        {
            if (password == null)
            {
                throw new ArgumentNullException(nameof(password), "Password cannot be null");
            }

            if (salt == null)
            {
                throw new ArgumentNullException(nameof(salt), "Salt cannot be null");
            }

            if (salt.Length != ARGON_SALTBYTES)
            {
                throw new SaltOutOfRangeException($"Salt must be {ARGON_SALTBYTES} bytes in length.");
            }

            if (opsLimit < 3)
            {
                throw new ArgumentOutOfRangeException(nameof(opsLimit), "opsLimit the number of passes, has to be at least 3");
            }

            if (memLimit <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(memLimit), "memLimit cannot be zero or negative");
            }

            if (outputLength <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(outputLength), "OutputLength cannot be zero or negative");
            }

            var buffer = new byte[outputLength];

            SodiumCore.Init();

            var ret = SodiumLibrary.crypto_pwhash(buffer, buffer.Length, password, password.Length, salt, opsLimit, memLimit, (int)alg);

            if (ret != 0)
            {
                throw new OutOfMemoryException("Internal error, hash failed (usually because the operating system refused to allocate the amount of requested memory).");
            }

            return(buffer);
        }
예제 #4
0
 /// <summary>Derives a secret key of any size from a password and a salt.</summary>
 /// <param name="password">The password.</param>
 /// <param name="salt">The salt.</param>
 /// <param name="limit">The limit for computation.</param>
 /// <param name="outputLength">The length of the computed output array.</param>
 /// <param name="alg">Argon Algorithm</param>
 /// <returns>Returns a byte array of the given size.</returns>
 /// <exception cref="ArgumentNullException"></exception>
 /// <exception cref="ArgumentOutOfRangeException"></exception>
 /// <exception cref="SaltOutOfRangeException"></exception>
 /// <exception cref="OutOfMemoryException"></exception>
 public static byte[] ArgonHashBinary(string password, string salt, StrengthArgon limit = StrengthArgon.Interactive, long outputLength = ARGON_SALTBYTES,
                                      ArgonAlgorithm alg = ArgonAlgorithm.Argon_2I13)
 {
     return(ArgonHashBinary(Encoding.UTF8.GetBytes(password), Encoding.UTF8.GetBytes(salt), limit, outputLength, alg));
 }