Ejemplo n.º 1
0
        /// <summary>
        /// Derive a key from a password.
        /// </summary>
        /// <remarks>Not all encryption types are supported.</remarks>
        /// <param name="key_encryption">The key encryption to use.</param>
        /// <param name="password">The password to derice from.</param>
        /// <param name="iterations">Iterations for the password derivation.</param>
        /// <param name="name_type">The key name type.</param>
        /// <param name="principal">Principal for key, in form TYPE/name@realm.</param>
        /// <param name="salt">Salt for the key.</param>
        /// <param name="version">Key Version Number (KVNO).</param>
        /// <returns></returns>
        public static KerberosAuthenticationKey DeriveKey(KerberosEncryptionType key_encryption, string password,
                                                          int iterations, KerberosNameType name_type, string principal, string salt, uint version)
        {
            if (principal is null)
            {
                throw new ArgumentNullException(nameof(principal));
            }

            byte[] key;

            switch (key_encryption)
            {
            case KerberosEncryptionType.ARCFOUR_HMAC_MD5:
            case KerberosEncryptionType.ARCFOUR_HMAC_MD5_56:
            case KerberosEncryptionType.ARCFOUR_HMAC_OLD:
            case KerberosEncryptionType.ARCFOUR_HMAC_OLD_EXP:
                key = MD4.CalculateHash(Encoding.Unicode.GetBytes(password));
                break;

            case KerberosEncryptionType.AES128_CTS_HMAC_SHA1_96:
                key = DeriveAesKey(password, MakeSalt(salt, principal), iterations, 16);
                break;

            case KerberosEncryptionType.AES256_CTS_HMAC_SHA1_96:
                key = DeriveAesKey(password, MakeSalt(salt, principal), iterations, 32);
                break;

            default:
                throw new ArgumentException($"Unsupported key type {key_encryption}", nameof(key_encryption));
            }

            return(new KerberosAuthenticationKey(key_encryption, key, name_type, principal, DateTime.Now, version));
        }