如果C ++ base64decode包含'\ 0',则返回垃圾数据

时间:2018-12-18 13:25:07

标签: c++ openssl binary base64 decoding

我们有一个证书文件(二进制),在多个位置都有'\ 0'。尝试使用openssl进行解码时,它会提供垃圾数据,而大小以前是完美的。

如果base64编码的数据中没有'\ 0',则相同的代码可以完美工作

我们尝试使用以下代码实现这一目标,但仍然无法读取文件

static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";

static inline bool is_base64(unsigned char c) {
    return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_decode(std::string const& encoded_string) {
    int in_len = encoded_string.size();
    int i = 0;
    int j = 0;
    int in_ = 0;
    int in_1 = 0;
    unsigned char char_array_4[4], char_array_3[3];

    std::string ret;
    std::ofstream outfile;
    outfile.open("output_file.pfx", std::ios::binary | std::ios::out);
    bool f = isalnum(encoded_string[in_]);
    while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
        char_array_4[i++] = encoded_string[in_]; in_++;
        if (i == 4) {
            for (i = 0; i < 4; i++)
            {
                char_array_4[i] = base64_chars.find(char_array_4[i]);
            }
            char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
            char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
            char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

            for (i = 0; (i < 3); i++)
            {
                if (char_array_3[i] != NULL)
                {
                    ret += char_array_3[i];
                    char val = char_array_3[i];
                    outfile.write(&val, sizeof(char));
                }
                else
                {
                    /*char str3[3155];
                    strcpy(str3, ret.c_str());
                    ret = "";
                    ret.append(str3, sizeof(str3));*/
                    ret += "NUL";
                    char val111 = char_array_3[i];
                    outfile.write(&val111, sizeof(char));
                }
            }
            i = 0;
        }
    }

    if (i) {
        for (j = 0; j < i; j++)
            char_array_4[j] = base64_chars.find(char_array_4[j]);

        char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
        char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);

        for (j = 0; (j < i - 1); j++)
        {
            if (char_array_3[i] != NULL)
            {
                ret += char_array_3[i];
                char val1 = char_array_3[i];
                outfile.write(&val1, sizeof(char));
            }
            else
            {
                ret += "NUL";
                char val11 = char_array_3[i];
                outfile.write(&val11, sizeof(char));
            }
        }//ret += char_array_3[j];
    }
    outfile.close();
    return ret;
}

int main()
{
    base64_decode("U4tR8mRzyrqpNhhFjkbEe4I6LTYXhL7PxkbddNTQ1yZ6ofZ4s1R/UOQsq6x+CNxB+yddPirwT0yPgtm6IC1qYF9GGQsOqXHkpTrmXf0GiXDVpm91EMnyxtMu74B3OMIYgxmjoeua7HoKQkW6/GRuCpgWIoZQq7uOaKIsc3k9HGgfAFk6vTGER1YJlG28lOhsiGccl0EqD0uhrBGNhFERfAzB2gaJjI1oRO87Q2NbevKHeZycpyXgazvtw9JigA+Hp3+Cy9LUIRvF6k5uv0DKxOs5cynqYslb1LfKqT0IvLjBl4gNHl+pG5/Ur70XzZTiO1+n5jWITPoslZ4slVkl4qiTaqNWHgLT6aSUhWwPlvK+7wlk+st5ykAuSIE2e3Lia+omBRH2LQfG1v7KaOJApF3k4D0li/4QWOJ3zLwBDHB6WCwMQfNS8vTRWM1yIO/o9417wJEpBlcr/B308vGheoTF9+qRKGDe0M5PNHeBbEHhgNkLsKvcS/31HK6Xd36cg85yvyLghQRr9Gyn7TUU5m6f6iSlx3u+yo1vT7BBV6OjbxPklwCIYCZWIIOJq10JXC+bSGPbTKZYXjQW90URKesUOMi9s+DS7BKVEr471AnEyazividrgivfHDNWQisIcOctpDFCfEBAa28PYjIj4KJo5bDkSluRVcVDJVrP2Ns=");
    return 0;
}    

1 个答案:

答案 0 :(得分:1)

尾部字节处理中存在错误,您使用i作为数组索引而不是j。由于i可以大于char_array_3的大小,因此会产生不确定的行为。正确的代码是:

    for (j = 0; (j < i - 1); j++)
    {
        if (char_array_3[j] != NULL)
        {
            ret += char_array_3[j];
            char val1 = char_array_3[j];
            outfile.write(&val1, sizeof(char));
        }
        else
        {
            ret += "NUL";
            char val11 = char_array_3[j];
            outfile.write(&val11, sizeof(char));
        }
    }