C ++,Google,ServiceAccount,OAUTH2_JWT->“ error_description”:“无效的JWT签名。”

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

得到“无效的JWT签名”。似乎只有签名是错误的。但是我只是不知道该怎么办。请帮助!

卷发效果100%Base64似乎工作正常。标头和声明解码是可以的。

如果有帮助,它会有一些信息here(REST)。

    // JWT HEADER
    std::string jwtHeader = base64_encode( "{\"alg\":\"RS256\",\"typ\":\"JWT\"}" );

    // JWT CLAIM
    std::string jwtClaim = base64_encode( ... );

    // JWT SIGNATURE
    std::string JWS  = jwtHeader + "." + jwtClaim;
    const char* privateKey = "-----BEGIN PRIVATE KEY-----\n...";

    // HASH        
        SHA256_CTX sha_ctx = { 0 };
        unsigned char digest[SHA256_DIGEST_LENGTH];
        SHA256_Init(&sha_ctx);
        SHA256_Update(&sha_ctx, JWS.c_str(), JWS.size());
        SHA256_Final(digest, &sha_ctx);

    // SIGN
        unsigned char* sig = nullptr;
        unsigned int slen = 0;
        BIO *priv_bio;
        BIO *pub_bio; 
        RSA *private_key; 
        priv_bio = BIO_new_mem_buf(privateKey, -1);
        private_key = PEM_read_bio_RSAPrivateKey(priv_bio, NULL, NULL, NULL);
        sig = (unsigned char*) malloc(RSA_size(private_key));

        if(RSA_sign(NID_sha256, (unsigned char*) digest, SHA256_DIGEST_LENGTH, sig, &slen, private_key) != 1) {
                ERR_print_errors_fp(stdout);
        } 

        // TOKEN REQUEST
        std::string sign = base64_encode(sig, slen);
        std::string requestStr = "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=" + JWS + "." + sign;

        headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
        curl_easy_setopt(curl_handle, CURLOPT_URL, "https://oauth2.googleapis.com/token");
        curl_easy_setopt( ... CURLOPT_POST, CURLOPT_HTTPHEADER, CURLOPT_POSTFIELDS ... );

更新:

这给了我signed_string_size == 256:

EVP_MD_CTX* m_RSASignCtx = EVP_MD_CTX_create();
EVP_PKEY* priKey  = EVP_PKEY_new()
EVP_PKEY_assign_RSA(priKey, rsa)
EVP_DigestSignInit(m_RSASignCtx,NULL, EVP_sha256(), NULL,priKey)
EVP_DigestSignUpdate(m_RSASignCtx, Msg, MsgLen) <= 0)
EVP_DigestSignFinal(m_RSASignCtx, NULL, MsgLenEnc)*EncMsg = (unsigned char*)malloc(*MsgLenEnc)
EVP_DigestSignFinal(m_RSASignCtx, *EncMsg, MsgLenEnc) EVP_MD_CTX_free(m_RSASignCtx)

但错误相同。

c++ openssl jwt google-oauth
1个回答
0
投票

OpenSSL documentation for EVP_PKEY_sign有一个您可以改编的示例,我认为:

#include <openssl/evp.h>
#include <openssl/rsa.h>

EVP_PKEY_CTX *ctx;
/* md is a SHA-256 digest in this example. */
unsigned char *md, *sig;
size_t mdlen = 32, siglen;
EVP_PKEY *signing_key;

/*
 * NB: assumes signing_key and md are set up before the next
 * step. signing_key must be an RSA private key and md must
 * point to the SHA-256 digest to be signed.
 */
ctx = EVP_PKEY_CTX_new(signing_key, NULL /* no engine */);
if (!ctx)
    /* Error occurred */
if (EVP_PKEY_sign_init(ctx) <= 0)
    /* Error */
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
    /* Error */
if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
    /* Error */

/* Determine buffer length */
if (EVP_PKEY_sign(ctx, NULL, &siglen, md, mdlen) <= 0)
    /* Error */
sig = OPENSSL_malloc(siglen);
if (!sig)
    /* malloc failure */

if (EVP_PKEY_sign(ctx, sig, &siglen, md, mdlen) <= 0)
    /* Error */

/* Signature is siglen bytes written to buffer sig */
© www.soinside.com 2019 - 2024. All rights reserved.