You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js如何从邮件中获取smime.p7s并提取发件人、组织名称及验证签名?

解决方案

原因说明

imap 包的 attributes 对象仅会识别显式标记为独立附件的普通文件,S/MIME 签名的 smime.p7s 属于邮件嵌套多部分(MIME)结构的内嵌部分,不会被 imap 直接解析到属性列表中,你在正文中看到的边界分隔内容就是未拆分的原始 MIME 结构。

实现步骤

1. 解析完整邮件MIME结构

使用专门的邮件解析库 mailparser 搭配 imap 读取完整邮件原始内容,自动拆分所有附件(包括S/MIME签名文件)。
首先安装依赖:

npm install imap mailparser

示例代码:

const Imap = require('imap');
const { simpleParser } = require('mailparser');

const imap = new Imap({
  user: '你的邮箱账号',
  password: '你的邮箱密码',
  host: 'IMAP服务器地址',
  port: 993,
  tls: true
});

imap.once('ready', () => {
  imap.openBox('INBOX', false, (err, box) => {
    // 搜索目标邮件,示例为拉取最新1封邮件
    imap.search(['ALL', ['UID', box.uidnext - 1]], (err, results) => {
      const f = imap.fetch(results, { bodies: '', struct: true });
      f.on('message', (msg) => {
        msg.on('body', (stream) => {
          // 直接将原始邮件流传入解析器
          simpleParser(stream, (err, parsed) => {
            // 筛选S/MIME签名附件
            const smimeSign = parsed.attachments.find(att => 
              att.contentType === 'application/pkcs7-signature'
            );
            if (smimeSign) {
              // smimeSign.content 就是p7s签名文件的Buffer内容
              handleSignature(smimeSign.content);
            }
          });
        });
      });
    });
  });
});
imap.connect();

2. 解析签名、提取信息并验证有效性

使用 node-forge 库处理p7s签名内容,提取发件人、组织信息并校验签名有效性。
安装依赖:

npm install node-forge

示例代码:

const forge = require('node-forge');

function handleSignature(p7sBuffer) {
  // 转换Buffer为forge可识别格式
  const p7Asn1 = forge.asn1.fromDer(p7sBuffer.toString('binary'));
  const pkcs7 = forge.pkcs7.messageFromAsn1(p7Asn1);

  // 提取签名者证书信息
  const signCert = pkcs7.certificates[0];
  const subjectAttrs = signCert.subject.attributes;
  // 提取发件人名称、所属组织
  const senderName = subjectAttrs.find(item => item.name === 'commonName')?.value;
  const orgName = subjectAttrs.find(item => item.name === 'organizationName')?.value;

  // 验证签名有效性(验证邮件未被篡改、签名和证书匹配)
  const signValid = pkcs7.verify();

  console.log('发件人名称:', senderName);
  console.log('所属组织:', orgName);
  console.log('签名是否有效:', signValid);
}

补充说明

  • 如果需要校验证书的信任链,可将信任的根CA证书导入到forge的证书存储中,避免信任不可信的自签名证书
  • 如果是加密S/MIME邮件,需要额外导入收件人私钥解密后才能进行后续校验
  • 该需求完全可以实现,不需要依赖外部服务

内容的提问来源于stack exchange,提问作者Stanislav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 07:12:03