我正在尝试使用OpenXML SDK创建受保护的电子表格文档。但是,生成的
WorkbookHashValue不正确,因此无法取消对工作簿的保护。
var password = Encoding.UTF8.GetBytes("123");
var salt = new byte[16];
new RNGCryptoServiceProvider().GetNonZeroBytes(salt);
var spinCount = 100000U;
using (var document = SpreadsheetDocument.Create("text.xlsx", SpreadsheetDocumentType.Workbook))
{
var workbookPart = document.AddWorkbookPart();
var workbook = new Workbook();
WorkbookProtection workbookProtection = new WorkbookProtection()
{
LockStructure = true,
WorkbookAlgorithmName = "SHA-512",
WorkbookHashValue = Convert.ToBase64String(GetPasswordHash(password, salt, spinCount)),
WorkbookSaltValue = Convert.ToBase64String(salt),
WorkbookSpinCount = spinCount
};
var sheets = new Sheets();
var sheet = new Sheet
{
Name = "Sheet 1",
SheetId = 1U,
Id = "rId1"
};
sheets.Append(sheet);
workbook.Append(workbookProtection);
workbook.Append(sheets);
workbookPart.Workbook = workbook;
var worksheetPart = workbookPart.AddNewPart<WorksheetPart>("rId1");
var worksheet = new Worksheet();
var sheetData = new SheetData();
worksheet.Append(sheetData);
worksheetPart.Worksheet = worksheet;
}
private byte[] GetPasswordHash(byte[] password, byte[] salt, uint spinCount)
{
using (var sha512 = SHA512.Create())
{
var buffer = new byte[salt.Length + password.Length];
Array.Copy(salt, buffer, salt.Length);
Array.Copy(password, 0, buffer, salt.Length, password.Length);
byte[] hash = sha512.ComputeHash(buffer);
buffer = new byte[hash.Length + 4];
for (var i = 0U; i < spinCount; i++)
{
Array.Copy(hash, buffer, hash.Length);
Array.Copy(BitConverter.GetBytes(i), 0, buffer, hash.Length, 4);
hash = sha512.ComputeHash(buffer);
}
return hash;
}
}
SALT VAQd0dyl7U67APquHio1lQ = =
的密码123
的正确哈希值应为2ZwXmW83qax0iUfzSkbhwAOVSDHAm6S/v9irWWTzdoFDgzO2Kc82P3Z9BAwbWqFLzN4rKaL0APOMzQ5tA7TBDw = = =
,但上述代码生成的z5ebojaXN/sD4ps9yurRCpSTDp + kSuTz + HN2PyKmGuicNgszAPKxfsE + kTgOEbGhT/VqSbwTd + + + oyAJxJh0L3A = =
。