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 MacIs48BytesLong() { byte[] data = CryptoRandom.NextBytesStatic(1227); byte[] key = CryptoRandom.NextBytesStatic(32); using (Stream tempStream = new MemoryStream()) { tempStream.Write(data, 0, data.Length); byte[] mac = MessageAuthenticationCodeValidator.CalculateMessageAuthenticationCode(key, tempStream); Assert.Equal(48, mac.Length); } }
public void MacCanBeValidated() { byte[] data = CryptoRandom.NextBytesStatic(1227); byte[] key = CryptoRandom.NextBytesStatic(32); using (Stream tempStream = new MemoryStream()) { tempStream.Write(data, 0, data.Length); bool error = false; byte[] mac = MessageAuthenticationCodeValidator.CalculateMessageAuthenticationCode(key, tempStream); try { MessageAuthenticationCodeValidator.ValidateMessageAuthenticationCode(key, mac, tempStream); } catch (DataIntegrityValidationException) { error = true; } Assert.False(error); } }
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); }