【问题标题】:Cannot decode base64+deflate data无法解码 base64+deflate 数据
【发布时间】:2018-10-30 13:17:06
【问题描述】:

我在解码以下 base64 字符串时迷路了

nVJPb4IwFL/7KUjvAgUM8CIuZiabicsSNR68deXhWKBteGVx336FbJnz4MG+U997/f1L5yTaxsBGn3Rvt0hGK0LPO7eNIhhnBes7BVpQTaBEiwRWwm75soHID8F02mqpGzZZrwpGScZjkUgpMolpFCfRLH/DPKlmaZXGMkqrMq/CMi6Zd8COaq0K5lCYtybqca3ICmVdK+TZlIfTONxzDtEMeHZk3grJ1krY8dW7tQaCgEepH7rikLoTEHaf2AWNPtXqodUlFonDVr++9rpgH1jq82BsusT8eWPa1yd9RLHdf7HFZD4MYBTTXWRwOwJBjnZQxRaDKnKy6tL4RFrWnWzQl7qdBxfIPzwGdlbYnu4I+wrh0Tm9A8U7iKbH28s0EsCulxKJBuLgmvm693f//6sW3w==

它应该是表示原始 XML 的 deflate 数据的有效 base64 数据。当我在这里尝试在线解码器时:https://www.samltool.com/decode.php 它给了我正确的 XML。

我正在做这两个步骤:

string text = MyClass::decode_base64(input);
text = MyClass::stringDeflateDecode(text);

首先我解码base64字符串:

string MyClass::decode_base64(string str)
{
    using namespace boost::archive::iterators;
    typedef transform_width<binary_from_base64<remove_whitespace<string::const_iterator> >, 8, 6> ItBinaryT;
    try {
        boost::erase_all(str, "\r");
        boost::erase_all(str, "\n");
        // If the input isn't a multiple of 4, pad with =
        size_t num_pad_chars((4 - str.size() % 4) % 4);
        str.append(num_pad_chars, '=');
        size_t pad_chars(std::count(str.begin(), str.end(), '='));
        std::replace(str.begin(), str.end(), '=', 'A'); // replace '=' by base64 encoding of '\0'
        string output(ItBinaryT(str.begin()), ItBinaryT(str.end()));
        output.erase(output.end() - pad_chars, output.end());
        return output;
    } catch (...) {
        return string("");
    }
}

代码基本上来自这里Decode Base64 String Using Boost,它适用于纯文本base64解码(无二进制放气数据)。

那我要解码deflate:

string MyClass::stringDeflateDecode(const std::string& data)
{
    stringstream compressed(data);
    stringstream decompressed;

    boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
    in.push(boost::iostreams::zlib_decompressor());
    in.push(compressed);
    boost::iostreams::copy(in, decompressed);

    return decompressed.str();
}

但是 ::copy 操作抛出异常:zlib error: iostream error

感谢任何提示!

【问题讨论】:

  • 既然它抱怨zlib,你有没有尝试解压SAML工具提供的压缩二进制数据?这样您就可以检查它是否与正在使用的算法或您以错误的方式使用的 C++ 代码 sn-p 有关。
  • 是的,使用base64 -d | zlib-flate -uncompress 的简单检查也失败了
  • 嗯,好吧,所以我将 zlib_decompressor() 构造函数行更改为 boost::iostreams::zlib_decompressor(boost::iostreams::zlib_params(boost::iostreams::zlib::default_compression, boost ::iostreams::zlib::deflated, 15, 8, boost::iostreams::zlib::default_strategy, true)) 现在可以正常工作,文本已成功解码。但我不确定这是否只是巧合。我可能正在提供应该在标题中的信息。也许如果用不同的参数编码它会失败?也许它总是默认的......

标签: c++ boost base64 decode deflate


【解决方案1】:

这是 Base-64 编码的原始数据。这意味着以 deflate 格式压缩数据,但没有围绕该 deflate 数据的 zlib 或 gzip 包装器。看起来zlib_decompressor 有一个noheader 选项,您应该将其设置为true

【讨论】:

    【解决方案2】:

    维基百科指定:

    通过 HTTP 重定向传输的 SAML 请求或响应分别具有 SAMLRequest 或 SAMLResponse 查询字符串参数。在发送之前,消息会按顺序进行压缩(没有标头和校验和)、base64 编码和 URL 编码。收到后,该过程被反转以恢复原始消息。

    这里的问题是没有标头和校验和。我认为 boost 没有你需要的库函数。

    【讨论】:

    • 感谢提示。是的,我已经在几周内发送了我的 SAML 请求,并且它可以与多个不同的公共身份提供者一起正常工作。这正是我必须做的:放气、base64 和 URL 编码。对于放气,我使用带有 boost 的反向机制: boost::iostreams::filtering_streambuf<:iostreams::input> out; out.push(boost::iostreams::zlib_decompressor(boost::iostreams::zlib_params(boost::iostreams::zlib::default_compression, boost::iostreams::zlib::deflated, 15, 8, boost::iostreams ::zlib::default_strategy, true))); IdP 接受了它。其他方式无效
    • 也许他们只是容忍并接受标题和校验和。所以我想我需要找到一些其他方法来“膨胀”数据,因为 samltool 页面证明了这些信息是可用的。
    • 我不能再编辑了,但在上面的示例中当然应该是 zlib_compressor。
    猜你喜欢
    • 2020-06-05
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    • 2011-03-15
    • 2015-11-16
    • 1970-01-01
    相关资源
    最近更新 更多