/// <summary> /// Validates the given key. Verifies the checksum and each sub key. /// </summary> /// <param name="hash">The hash algorithm used to compute the sub key.</param> /// <param name="checksum">The checksum algorithm used to compute the key's checksum.</param> /// <param name="key">The key to validate.</param> /// <param name="subkeyIndex">The index (zero based) of the sub key to check.</param> /// <param name="subkeyBase">The unsigned base integer used create the sub key.</param> /// <returns>true if the is valid; false otherwise.</returns> public static bool ValidateKey(IChecksum16 checksum, IHash hash, string key, int subkeyIndex, uint subkeyBase) { var bytes = GetKeyBytes(key); var seed = BitConverter.ToUInt32(bytes, 0); return(ValidateKey(hash, checksum, bytes, seed, subkeyIndex, subkeyBase)); }
//validates the checksum private static bool ValidateChecksum(IChecksum16 checksum, byte[] key) { var sum = BitConverter.ToUInt16(key, key.Length - 2); var keyBytes = new byte[key.Length - 2]; Buffer.BlockCopy(key, 0, keyBytes, 0, keyBytes.Length); return(sum == checksum.Compute(keyBytes)); }
/// <summary> /// Validates the given key. Verifies the given string seed matches /// the seed embedded in the key, verifies the checksum and each sub key. /// This version is useful if the seed used to generate a key was derived /// from some user information such as the user's name, e-mail, etc. /// </summary> /// <param name="hash">The hash algorithm used to compute the sub key.</param> /// <param name="checksum">The checksum algorithm used to compute the key's checksum.</param> /// <param name="key">The key to validate.</param> /// <param name="subkeyIndex">The index (zero based) of the sub key to check.</param> /// <param name="subkeyBase">The unsigned base integer used create the sub key.</param> /// <param name="seedString">The string used to generate the seed for the key.</param> /// <returns>true if the is valid; false otherwise.</returns> public static bool ValidateKey(IChecksum16 checksum, IHash hash, string key, int subkeyIndex, uint subkeyBase, string seedString) { var bytes = GetKeyBytes(key); var seed = BitConverter.ToUInt32(bytes, 0); if (Hash.Compute(Encoding.UTF8.GetBytes(seedString)) != seed) { return(false); } return(ValidateKey(hash, checksum, bytes, seed, subkeyIndex, subkeyBase)); }
//validates one sub key. private static bool ValidateKey(IHash hash, IChecksum16 checksum, byte[] key, uint seed, int subkeyIndex, uint subkeyBase) { if (!ValidateChecksum(checksum, key)) { return(false); } var offset = subkeyIndex * 4 + 4; if (subkeyIndex < 0 || offset + 4 > key.Length - 2) { throw new IndexOutOfRangeException("Sub key index is out of bounds"); } var subKey = BitConverter.ToUInt32(key, offset); var expected = hash.Compute(BitConverter.GetBytes(seed ^ subkeyBase)); return(expected == subKey); }
/// <summary> /// Initializes a new instance of the <see cref="PartialKeyGenerator"/> class. /// </summary> /// <param name="checksum">The checksum algorithm to use.</param> /// <param name="hashFunctions">A list of hash functions to use. If the number of /// hash functions is less than the number <paramref name="baseKeys"/>, then the /// functions cycles back to the first function. It is recommended to use several /// different hash functions.</param> /// <param name="baseKeys">The integers used to generate the sub key.</param> public PartialKeyGenerator(IChecksum16 checksum, IEnumerable <IHash> hashFunctions, uint[] baseKeys) { if (checksum == null) { throw new ArgumentNullException("checksum"); } if (hashFunctions == null) { throw new ArgumentNullException("hashFunctions"); } if (baseKeys == null) { throw new ArgumentNullException("baseKeys"); } _checksum = checksum; _baseKeys = baseKeys; foreach (var hash in hashFunctions) { _hashFunctions.Add(hash); } }
/// <summary> /// Initializes a new instance of the <see cref="PartialKeyGenerator"/> class. /// </summary> /// <param name="checksum">The checksum algorithm to use.</param> /// <param name="hash">The hash algorithm to use.</param> /// <param name="baseKeys">The integer bases keys used to generate the sub keys (one base key for each sub key).</param> public PartialKeyGenerator(IChecksum16 checksum, IHash hash, uint[] baseKeys) : this(checksum, new[] { hash }, baseKeys) { }