C ++ base64decode возвращает ненужные данные, если они содержат '\ 0' - PullRequest
0 голосов
/ 18 декабря 2018

У нас есть файл сертификата (двоичный), имеющий '\ 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 голосов
/ 18 декабря 2018

В обработке завершающих байтов есть ошибка, вы используете 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));
        }
    }
...