得到“无效的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)
但错误相同。
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 */