예제 #1
0
        /// <summary>
        /// Creates a secret key with the specified number of bits of entropy and specified
        /// <see cref="CryptoSecureRequirement"/> to be shared with the user on wich the future valid TOTP codes will
        /// be based.
        /// </summary>
        /// <param name="bits">The number of bits of entropy to use.</param>
        /// <param name="cryptoSecureRequirement">The <see cref="CryptoSecureRequirement"/> to ensure cryptographically secure RNG's.</param>
        /// <returns>
        /// Returns a string of random values in 'Base32 alphabet' to be shared with the user / stored with the account.
        /// </returns>
        /// <exception cref="CryptographicException">
        /// Thrown when the <see cref="IRngProvider"/> of the instance is not cryptographically secure and the
        /// <see cref="CryptoSecureRequirement"/> requires a cryptographically secure RNG.
        /// </exception>
        public string CreateSecret(int bits, CryptoSecureRequirement cryptoSecureRequirement)
        {
            if (cryptoSecureRequirement == CryptoSecureRequirement.RequireSecure && !RngProvider.IsCryptographicallySecure)
            {
                throw new CryptographicException("RNG provider is not cryptographically secure");
            }

            int bytes = (int)Math.Ceiling((double)bits / 5);    // We use 5 bits of each byte (since we have a

            // 32-character 'alphabet' / base32)

            // Note that we DO NOT actually "base32 encode" the random bytes, we simply take 5 bits from each random
            // byte and map these directly to letters from the base32 alphabet (effectively 'base32 encoding on the fly').
            return(string.Concat(RngProvider.GetRandomBytes(bytes).Select(v => Base32.Base32Alphabet[v & 31])));
        }
예제 #2
0
        /// <summary>
        /// Creates a secret key with the specified number of bits of entropy and specified 
        /// <see cref="CryptoSecureRequirement"/> to be shared with the user on wich the future valid TOTP codes will
        /// be based.
        /// </summary>
        /// <param name="bits">The number of bits of entropy to use.</param>
        /// <param name="cryptoSecureRequirement">The <see cref="CryptoSecureRequirement"/> to ensure cryptographically secure RNG's.</param>
        /// <returns>
        /// Returns a string of random values in 'Base32 alphabet' to be shared with the user / stored with the account.
        /// </returns>
        /// <exception cref="CryptographicException">
        /// Thrown when the <see cref="IRngProvider"/> of the instance is not cryptographically secure and the
        /// <see cref="CryptoSecureRequirement"/> requires a cryptographically secure RNG.
        /// </exception>
        public string CreateSecret(int bits, CryptoSecureRequirement cryptoSecureRequirement)
        {
            if (cryptoSecureRequirement == CryptoSecureRequirement.RequireSecure && !this.RngProvider.IsCryptographicallySecure)
                throw new CryptographicException("RNG provider is not cryptographically secure");

            int bytes = (int)Math.Ceiling((double)bits / 5);    // We use 5 bits of each byte (since we have a
                                                                // 32-character 'alphabet' / base32)

            // Note that we DO NOT actually "base32 encode" the random bytes, we simply take 5 bits from each random 
            // byte and map these directly to letters from the base32 alphabet (effectively 'base32 encoding on the fly').
            return string.Concat(this.RngProvider.GetRandomBytes(bytes).Select(v => Base32.Base32Alphabet[v & 31]));
        }