向澳大利亚边防部队(ABF)通过S/MIME发送EDI文件时遭遇‘malformed PKCS#7’错误的技术求助
向澳大利亚边防部队(ABF)通过S/MIME发送EDI文件时遭遇‘malformed PKCS#7’错误的技术求助
各位大佬,我现在卡在一个问题上快崩溃了:我正在搭建一套系统,要通过S/MIME加密邮件给澳大利亚边防部队(ABF)发送EDI文件(比如CUSCAR格式),但每次发过去都只收到ABF的malformed PKCS#7错误提示,连最基础的确认回复都没有,看起来消息在他们那边的解密/解析阶段直接就被判无效了,完全摸不清到底哪里出问题了!
当前的实现方案
S/MIME生成流程(PHP + OpenSSL)
我这边采用先签名再加密的标准流程:
- 用
openssl_pkcs7_sign()给EDI文件用我们的自有证书和私钥做签名 - 再用ABF提供的公钥,通过
openssl_pkcs7_encrypt()把签名后的消息加密 - 最终生成
.p7m格式文件,包含签名和加密后的内容,全程使用MIME格式而非二进制DER格式
邮件发送(PHPMailer)
用PHPMailer把生成好的.p7m作为附件发送,并且严格按照规范设置了MIME头:
Content-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name="file.p7m" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="file.p7m"
我们已经尝试过的所有排查步骤
为了找出问题,我们几乎把能想到的点都试了一遍,但还是无法解决:
格式与编码检查
- 特意移除了OpenSSL中的
PKCS7_BINARY标志,确保输出是纯MIME格式而非二进制 - 验证过生成的
.p7m文件开头是0x30(ASN.1序列的正确标识) - 反复确认邮件中的附件是标准的base64编码,没有编码错误或乱码
有效性验证
- 用
openssl smime -verify -inform SMIME和openssl asn1parse命令能正常解析我们生成的PKCS#7文件,无任何报错 - 文件大小稳定在4-5KB左右,不存在截断或传输中损坏的情况
但不管怎么调整,ABF那边的回复永远只有一句:malformed PKCS#7,完全不给任何细节,实在是无从下手。
代码示例(PHP + OpenSSL)
给大家贴一下我们生成.p7m的核心代码,有没有大佬能看出哪里有问题?
<?php $inputFile = 'seacr.edi'; $signedFile = tempnam(sys_get_temp_dir(), 'signed_'); $encryptedFile = 'smime.p7m'; // 证书与密钥文件路径 $signCert = 'signing.pem'; $privateKey = 'key.pem'; $signKeyPassword = ''; $recipientCert = 'abf_public_cert.pem'; // 检查必要文件是否存在 if (!file_exists($inputFile) || !file_exists($signCert) || !file_exists($recipientCert)) { die("缺失必要的输入文件或证书文件!\n"); } // 第一步:对EDI文件进行签名(生成multipart/signed格式的输出) $signSuccess = openssl_pkcs7_sign( $inputFile, $signedFile, "file://$signCert", ["file://$privateKey", $signKeyPassword], [], PKCS7_DETACHED ); if (!$signSuccess) { while ($msg = openssl_error_string()) { echo "签名错误:$msg\n"; } exit; } // 第二步:对签名后的内容进行加密(生成MIME格式的PKCS#7信封) $encryptTemp = tempnam(sys_get_temp_dir(), 'encrypted_'); $encryptSuccess = openssl_pkcs7_encrypt( $signedFile, $encryptTemp, "file://$recipientCert", [], 0, OPENSSL_CIPHER_AES_256_CBC ); if (!$encryptSuccess) { echo "加密失败!\n"; while ($msg = openssl_error_string()) { echo "加密错误:$msg\n"; } exit; } // 输出最终的.p7m文件 file_put_contents($encryptedFile, file_get_contents($encryptTemp)); ?>
邮件附件添加代码
这部分是用PHPMailer添加附件的代码:
$mail->addAttachment( $smimeFile, 'smime.p7m', 'base64', 'application/x-pkcs7-mime; smime-type=enveloped-data' );
想请教的问题
有没有大佬成功通过S/MIME给ABF发送过EDI文件?ABF对S/MIME格式的消息有没有什么特殊的、官方文档里没写的要求?比如换行符必须是CRLF还是LF?加密算法有没有指定必须用某一种?或者Content-Type头有没有什么特殊的写法?
我们已经反复啃完了ABF提供的所有开发者文档,也发了好几封邮件追问细节,但对方永远只回复malformed PKCS#7让我们自己修复,完全不给任何有用的信息,实在卡在这里动不了了,求各位大佬支支招!
内容来源于stack exchange
相关产品推荐
相关产品推荐

