Как я могу создать base64url из кодированной строки sha256 в C ++ - PullRequest
0 голосов
/ 22 апреля 2020

Этот C# код:

            string code_verifier = "xe-V-ykFyCazK3jCWwqRCZHKAKJ0MqdZs8F6xenxjFE";
            byte[] sha256verifier = sha256(code_verifier);
            string code_challenge = base64urlencodeNoPadding(sha256verifier);
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < sha256verifier.Length; i++)
                builder.Append(sha256verifier[i].ToString("x2"));
            output("code_verifier: " + code_verifier);
            output("builder: " + builder.ToString());
            output("code_challenge: " + code_challenge); 

Дает такие результаты:

    code_verifier: xe-V-ykFyCazK3jCWwqRCZHKAKJ0MqdZs8F6xenxjFE
    builder: 8b6526951bf46153a9a276be579ee1070f86e0812fbde8b8c37a3e64c3368525
    code_challenge: i2UmlRv0YVOpona-V57hBw-G4IEvvei4w3o-ZMM2hSU

Я пытаюсь сделать то же самое в C ++, используя poco, вот мой код:

    std::string verifier_ = "xe-V-ykFyCazK3jCWwqRCZHKAKJ0MqdZs8F6xenxjFE";
    std::string sha256verifier = sha256(verifier_);
    std::stringstream ss;
    Poco::Base64Encoder b64enc(ss, Poco::BASE64_URL_ENCODING || Poco::BASE64_NO_PADDING);
    b64enc << sha256(sha256verifier);
    std::string challenge = ss.str();
    cout << "verifier: " << verifier_ << endl;
    cout << "sha256verifier: " << sha256verifier << endl;
    cout << "challenge: " << challenge << endl;

Результат:

verifier: xe-V-ykFyCazK3jCWwqRCZHKAKJ0MqdZs8F6xenxjFE
sha256verifier: 8b6526951bf46153a9a276be579ee1070f86e0812fbde8b8c37a3e64c3368525
challenge: YTIzY2U1YTYxY2IwMTU0ZmFhZjU1ZWY2ZDEyNGYzZjE3MjQzN2M1MTExNmRiZTY1ZDU1ZTc1NWY2ZjMyNjZi

Функция C# sha256 () возвращает байтовый массив из 32 элементов, который base64urlencodeNoPadding преобразует в строку из 32 символов.

Функция C ++ sha256 () возвращает 32-элементную строку в шестнадцатеричном формате с теми же данными, которые Poco :: Base64Encoder превращает в строку из 64 элементов, которая не имеет отношения к строке C#.

Как получить то же самое результаты из C ++, полученные из C#?

Это моя функция poco sha256

std::string::sha256(std::string buffer) {
    Poco::Crypto::RSAKey key(Poco::Crypto::RSAKey::KL_2048,
    Poco::Crypto::RSAKey::EXP_LARGE);
    Poco::Crypto::RSADigestEngine eng(key, "SHA256");
    eng.update(buffer.c_str(), buffer.size());
    const auto& sig = eng.digest(); // We just want the digest, unsigned.
    return Poco::DigestEngine::digestToHex(sig);
}

1 Ответ

1 голос
/ 22 апреля 2020

В вашем решении C ++ есть 2 проблемы:

  • вы делаете SHA-256 дважды - при sha256(verifier_) и sha256(sha256verifier)
  • Poco::DigestEngine::digestToHex преобразует SHA-256 сумма в шестнадцатеричную строку

Попробуйте что-то вроде этого (не проверено):

std::string verifier_ = "xe-V-ykFyCazK3jCWwqRCZHKAKJ0MqdZs8F6xenxjFE";
auto sha256verifier = sha256(verifier_);
std::string challenge = toBase64(sha256verifier);
cout << "verifier: " << verifier_ << endl;
cout << "sha256verifier: " << toHex(sha256verifier) << endl;
cout << "challenge: " << challenge << endl;

std::vector<unsigned char> sha256(std::string const& buffer) {
    Poco::Crypto::RSAKey key(Poco::Crypto::RSAKey::KL_2048, Poco::Crypto::RSAKey::EXP_LARGE);
    Poco::Crypto::RSADigestEngine eng(key, "SHA256");
    eng.update(buffer.c_str(), buffer.size());
    return eng.digest();
}

std::string toBase64(std::vector<unsigned char> const& sig) {
    std::stringstream ss;
    Poco::Base64Encoder b64enc(ss, Poco::BASE64_URL_ENCODING || Poco::BASE64_NO_PADDING);
    b64enc.write((const char*)sig.data(), sig.size());
    b64enc.close();
    return ss.str();
}

std::string toHex(std::vector<unsigned char> const& sig) {
    return Poco::DigestEngine::digestToHex(sig);
}
...