如何在C++中用sha256编码的字符串创建base64url?

问题描述 投票:0回答:1

这段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);
}
c++ encryption poco
1个回答
1
投票

你的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);
}
© www.soinside.com 2019 - 2024. All rights reserved.