能否不下载附件直接获取其哈希值?Office-js技术问询
问题解答:无需下载Office附件直接计算哈希并提交至恶意文件分析库
核心结论
目前仅通过Office JS无法实现不下载附件就计算哈希——因为Office JS的沙箱限制,它只能获取附件的元数据(文件名、大小、ID等),无法直接读取附件的原始二进制内容,而计算MD5/SHA等哈希必须依赖完整的文件字节流。
可行替代方案:后端中转处理
既然Office JS本身拿不到文件内容,我们可以借助后端服务完成“获取文件内容→计算哈希→提交分析”的流程,具体步骤如下:
Step 1:Office JS传递附件信息到后端
用Office JS获取当前邮件/文档中附件的ID和父项ID,然后调用自己的后端接口,把这些信息传过去。
示例代码:async function processAttachmentHash() { // 获取当前邮箱项的附件 const mailboxItem = Office.context.mailbox.item; const attachments = mailboxItem.attachments; if (attachments.length === 0) return; // 取第一个附件为例,可扩展为批量处理 const targetAttachment = attachments[0]; try { // 调用后端接口 const res = await fetch('/api/attachment-hash', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ itemId: mailboxItem.itemId, attachmentId: targetAttachment.id }) }); const { md5, sha256 } = await res.json(); // 提交哈希到VirusTotal await submitHashToVT(sha256); } catch (err) { console.error('处理失败:', err); } } async function submitHashToVT(sha256Hash) { // 调用VirusTotal API查询哈希 const vtApiKey = '你的API密钥'; const res = await fetch(`https://www.virustotal.com/api/v3/files/${sha256Hash}`, { headers: { 'x-apikey': vtApiKey } }); const analysisResult = await res.json(); // 处理分析结果,比如展示给用户 console.log('分析结果:', analysisResult); }Step 2:后端通过Graph API获取附件内容并计算哈希
后端需要集成Microsoft Graph API,用传入的itemId和attachmentId调用/me/messages/{messageId}/attachments/{attachmentId}/$value接口获取附件的二进制数据,然后用对应语言的哈希工具计算MD5/SHA值(比如Node.js用crypto模块)。
示例Node.js后端片段:const crypto = require('crypto'); const { Client } = require('@microsoft/microsoft-graph-client'); const { TokenCredentialAuthenticationProvider } = require('@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials'); const { ClientSecretCredential } = require('@azure/identity'); // 初始化Graph客户端 const credential = new ClientSecretCredential( '你的租户ID', '你的应用ID', '你的应用密钥' ); const authProvider = new TokenCredentialAuthenticationProvider(credential, { scopes: ['https://graph.microsoft.com/.default'] }); const graphClient = Client.initWithMiddleware({ authProvider }); // 计算哈希的工具函数 function calculateHash(buffer, algorithm) { return crypto.createHash(algorithm).update(buffer).digest('hex'); } // 处理请求的接口 app.post('/api/attachment-hash', async (req, res) => { const { itemId, attachmentId } = req.body; try { // 获取附件二进制数据 const attachmentStream = await graphClient .api(`/me/messages/${itemId}/attachments/${attachmentId}/$value`) .getStream(); // 转换为Buffer计算哈希 const buffer = []; for await (const chunk of attachmentStream) { buffer.push(chunk); } const fileBuffer = Buffer.concat(buffer); const md5 = calculateHash(fileBuffer, 'md5'); const sha256 = calculateHash(fileBuffer, 'sha256'); res.json({ md5, sha256 }); } catch (err) { res.status(500).json({ error: err.message }); } });
权限注意事项
- Office插件需要在
manifest.xml中声明Mailbox.ReadWrite权限,才能访问附件ID和邮件项ID。 - 后端应用需要在Azure AD中注册,并申请
Mail.Read或Mail.ReadWrite的应用权限,才能通过Graph API读取附件内容。
内容的提问来源于stack exchange,提问作者LB Kerrigan
相关产品推荐
相关产品推荐

