public async Task WriteChecksAndEmbeddedDataAsync() { OutData.Position = 0; await OutData.WriteAsync(BitConverter.GetBytes(MagicNumber), 0, 4); await OutData.WriteAsync(BitConverter.GetBytes(DataVersionNumber), 0, 2); await OutData.WriteAsync(BitConverter.GetBytes(MinCompatibleDataVersionNumber), 0, 2); await OutData.WriteAsync(IV, 0, 16); await OutData.WriteAsync(Salt, 0, 32); var kcv = KeyCheckValueValidator.GenerateKeyCheckValue(Key); OutData.Write(kcv, 0, 19); long currentPosition = OutData.Position; var mac = MessageAuthenticationCodeValidator.CalculateMessageAuthenticationCode(Key, OutData, HeaderSize); Debug.Assert(currentPosition == OutData.Position, "Stream position is changed after generating MAC"); await OutData.WriteAsync(mac, 0, 48); OutData.Position = 0; }
public void AlteredKeyCheckValueIsNotValid() { byte[] key = CryptoRandom.NextBytesStatic(32); byte[] kcv = KeyCheckValueValidator.GenerateKeyCheckValue(key); if (key[0] > 120) { key[0]--; } else { key[0]++; } bool exceptionWasThrown = false; try { KeyCheckValueValidator.ValidateKeyCheckValue(key, kcv); } catch (KeyCheckValueValidationException) { exceptionWasThrown = true; } Assert.True(exceptionWasThrown, "Validation of KCV should have failed, but it didn't"); }
public void UnalteredKeyCheckValueIsValid() { byte[] key = CryptoRandom.NextBytesStatic(32); byte[] kcv = KeyCheckValueValidator.GenerateKeyCheckValue(key); bool exceptionWasThrown = false; try { KeyCheckValueValidator.ValidateKeyCheckValue(key, kcv); } catch (KeyCheckValueValidationException) { exceptionWasThrown = true; } Assert.False(exceptionWasThrown, "Validation of KCV has failed"); }
private ValidationResult ReadAndValidateDataForDecryption(bool skipKeyCheck) { var result = new ValidationResult(); // InData.Position = 0; if (InData.Length < HeaderSize) { result.SetException(DataFormatValidationException.DataValidationErrors.DataIsTooShort); return(result); } int magic = GetHeaderInt32(0); short dataVersion = GetHeaderInt16(4); short minDataVersion = GetHeaderInt16(6); IV = GetIV(); byte[] salt = GetHeaderBytes(24, 32); KeyCheckValue = GetHeaderBytes(56, 19); MessageAuthenticationCode = GetHeaderBytes(75, 48); int additionalDataLength = GetHeaderInt32(123); // additional data not supported in this version if (EmbedSalt) { Salt = salt; Key = new PasswordHasher().HashPassword(_password, salt); } else { salt = Salt; } if (magic != MagicNumber) { result.SetException(DataFormatValidationException.DataValidationErrors.InvalidMagicNumber); return(result); } result.DataFormatIsValid = true; if (minDataVersion != MinCompatibleDataVersionNumber) { result.SetException(DataFormatValidationException.DataValidationErrors.UnsupportedDataVersion); return(result); } result.DataFormatVersionIsValid = true; result.DataFormatVersionIsExact = dataVersion == DataVersionNumber; InData.Position = HeaderSize + additionalDataLength; HeaderTotalSize = (int)InData.Position; if (!skipKeyCheck) { bool kcvPass = KeyCheckValueValidator.ValidateKeyCheckValueInternal(Key, KeyCheckValue); if (!kcvPass) { result.SetException(DataFormatValidationException.DataValidationErrors.KeyCheckValueValidationError); return(result); } } result.KeyIsValid = true; if (!skipKeyCheck) { bool macIsValid = MessageAuthenticationCodeValidator.ValidateMessageAuthenticationCodeInternal(Key, MessageAuthenticationCode, InData, HeaderSize); if (!macIsValid) { result.SetException(DataFormatValidationException.DataValidationErrors.DataIntegrityValidationError); return(result); } } result.DataIntegrityIsValid = true; return(result); }
public void KeyCheckValidIs19BytesLong() { byte[] key = CryptoRandom.NextBytesStatic(32); byte[] kcv = KeyCheckValueValidator.GenerateKeyCheckValue(key); Assert.True(kcv.Length == 19, "KCV is not 19 bytes long"); }