盒马云数据是盒马内部自定义的AES-128-CBC加密+base64编码二进制格式(.hmd/.box),需先base64解码,再用OpenSSL解密,最后unserialize或json_decode还原为PHP数组。

盒马云数据是什么格式?PHP怎么识别它
盒马云数据不是标准协议,而是盒马内部系统导出的一种自定义二进制封装格式(常见后缀为 .hmd 或 .box),本质是加密+序列化的 PHP 数组或 JSON 结构。PHP 原生不支持直接读取,必须先解密再反序列化。
你拿到的文件大概率是 AES-128-CBC 加密 + base64 编码后的 payload,密钥和 IV 通常由盒马提供(如通过对接文档或环境变量),不会写在文件里。
- 直接
file_get_contents()读出来是一串乱码或 base64 字符,不是 JSON 或数组 -
unserialize()会报Notice: unserialize(): Error at offset—— 因为前面是密文,不是原生 PHP 序列化流 - 用
json_decode()返回null,且json_last_error_msg()显示Syntax error
PHP解密盒马云数据的最小可行代码
假设你已拿到密钥 $key 和 IV $iv(十六进制字符串或原始字节),且文件内容是 base64 编码的密文:
$raw = file_get_contents('/path/to/data.box');
$ciphertext = base64_decode($raw);
$decrypted = openssl_decrypt($ciphertext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
$data = @unserialize($decrypted); // 注意:盒马有时也用 json_encode 后加密,此时改用 json_decode($decrypted, true)
if ($data === false && !is_array($data)) {
throw new Exception('解密或反序列化失败,请检查 key/iv 或确认原始格式');
}
- 确保
$key长度为 16 字节(128 位),不足补\0,过长截断;$iv必须恰好 16 字节 - 不要用
mcrypt(已废弃)或自己写 XOR 解密逻辑——盒马用的是标准 OpenSSL 流程 - 如果对接文档里给的是 base64 格式的 key/iv,记得先
base64_decode()再传给openssl_decrypt
写回盒马云数据要注意什么
盒马系统对写入数据有严格校验:除了加密,还可能要求添加时间戳、签名字段(如 sign)、版本头(如 HMDv2 前缀),否则上传后提示 Invalid data format 或静默丢弃。
立即学习“PHP免费学习笔记(深入)”;
- 先用
serialize($data)或json_encode($data, JSON_UNESCAPED_UNICODE)生成原始 payload(确认对方接收哪种) - 加密前务必补零至块对齐(PKCS#7),可用
openssl_encrypt自动处理,别手动 pad - 最终写入文件前,必须
base64_encode()—— 盒马服务端只认 base64 编码的密文体 - 部分接口要求 HTTP header 里带
X-Boxma-Signature,那是另一个 HMAC-SHA256 签名,和文件内容加密无关,别混淆
调试时最常卡在哪几个点
90% 的失败不是算法问题,而是元信息错配:
- 密钥/IV 拿的是测试环境的,但数据是生产环境加密的(反之亦然)
- 以为文件是 UTF-8,实际是二进制流,用
mb_convert_encoding()转码后破坏了密文 - 用
file_put_contents()写入时没加FILE_BINARYflag,Windows 下换行符被悄悄替换 - 盒马某次升级后改用 AES-256-CBC,但文档没同步更新,key 长度还是按 128 位传的
建议把加密前后各取前 32 字节 hexdump 对比,确认是否真正在解密,而不是在 decode base64 或 trim 空格上浪费时间。



















