private static void ConfirmValid(bool expectedResult, String docIdHex, String saltDataHex, String saltHashHex, String password) { byte[] docId = fromHex(docIdHex); byte[] saltData = fromHex(saltDataHex); byte[] saltHash = fromHex(saltHashHex); Biff8EncryptionKey key; if (password == null) { key = Biff8EncryptionKey.Create(docId); } else { key = Biff8EncryptionKey.Create(password, docId); } bool actResult = key.Validate(saltData, saltHash); if (expectedResult) { Assert.IsTrue(actResult, "validate failed"); } else { Assert.IsFalse(actResult, "validate succeeded unexpectedly"); } }
public RecordInputStream CreateDecryptingStream(Stream original) { FilePassRecord fpr = _filePassRec; String userPassword = Biff8EncryptionKey.CurrentUserPassword; Biff8EncryptionKey key; if (userPassword == null) { key = Biff8EncryptionKey.Create(fpr.DocId); } else { key = Biff8EncryptionKey.Create(userPassword, fpr.DocId); } if (!key.Validate(fpr.SaltData, fpr.SaltHash)) { throw new EncryptedDocumentException( (userPassword == null ? "Default" : "Supplied") + " password is invalid for docId/saltData/saltHash"); } return(new RecordInputStream(original, key, _InitialRecordsSize)); }
/// <summary> /// Returns true when the Excel file is password protected /// </summary> /// <param name="compoundFile">The Excel file to check</param> /// <returns></returns> /// <exception cref="OEFileIsCorrupt">Raised when the file is corrupt</exception> public static bool IsPasswordProtected(CompoundFile compoundFile) { try { if (compoundFile.RootStorage.ExistsStream("EncryptedPackage")) { return(true); } if (!compoundFile.RootStorage.ExistsStream("WorkBook")) { throw new OEFileIsCorrupt("Could not find the WorkBook stream in the file '" + compoundFile.FileName + "'"); } var stream = compoundFile.RootStorage.GetStream("WorkBook") as CFStream; if (stream == null) { return(false); } var bytes = stream.GetData(); using (var memoryStream = new MemoryStream(bytes)) using (var binaryReader = new BinaryReader(memoryStream)) { // Get the record type, at the beginning of the stream this should always be the BOF var recordType = binaryReader.ReadUInt16(); // Something seems to be wrong, we would expect a BOF but for some reason it isn't so stop it if (recordType != 0x809) { throw new OEFileIsCorrupt("The file '" + Path.GetFileName(compoundFile.FileName) + "' is corrupt"); } var recordLength = binaryReader.ReadUInt16(); binaryReader.BaseStream.Position += recordLength; // Search after the BOF for the FilePass record, this starts with 2F hex recordType = binaryReader.ReadUInt16(); if (recordType != 0x2F) { return(false); } binaryReader.ReadUInt16(); var filePassRecord = new FilePassRecord(memoryStream); var key = Biff8EncryptionKey.Create(filePassRecord.DocId); return(!key.Validate(filePassRecord.SaltData, filePassRecord.SaltHash)); } } catch (OEExcelConfiguration) { // If we get an OCExcelConfiguration exception it means we have an unknown encryption // type so we return a false so that Excel itself can figure out if the file is password // protected return(false); } catch (CFFileFormatException) { // It seems the file is just a normal Microsoft Office 2007 and up Open XML file return(false); } }