mbedtls_rsa_rsassa_pkcs1_v15_sign堆栈溢出

发布于 2025-01-19 00:19:33 字数 4957 浏览 4 评论 0原文

我是一个业余爱好者,这是我第一次进入C ++和嵌入式系统的世界。我正在用 mbedtls

我正在尝试创建一个jwt到。这涉及SHA256散列一些base64编码的JSON对象(header.claim),然后rsassa-pkcs1-v1_5-Sign签名。

我似乎还可以到签名部分。我的理解是,我可以使用MBEDTLS_PK_PARSE_KEY来解析私钥,然后将MBEDTLS_PK_CONTEXT与MBEDTLS_RSA_RSASASA_PKCSA_PKCS1_V15_SIGN一起使用。

我的问题是两倍,我不确定我正在正确地使用MBEDTLS_RSA_RSASA_PKCS1_V15_SIGN,因为所得的base64编码签名出现在控制台中的以下内容。在编码的JSON对象是可以读取的。

encodedHeader: ewoJImFsZyI6CSJSUzI1NiIsCgkidHlwIjoJIkpXVCIKfQ==
encodedSignature: ������������������������������������������������������...

另外,随着这种方法返回,我得到了一个堆栈溢出,我不确定它来自哪里。

***ERROR*** A stack overflow in task main has been detected.


Backtrace:0x40081c0a:0x3ffb82700x40085a4d:0x3ffb8290 0x40088716:0x3ffb82b0 0x4008748f:0x3ffb8330 0x40085b4c:0x3ffb8350 0x40085afe:0x00000000  |<-CORRUPTED




ELF file SHA256: 4307a925ab3c9b48

这是我的代码,任何帮助将不胜感激。

// Encode Header
unsigned char encodedHeader[92];
size_t encodedHeaderSize;
const unsigned char* headerRecast = reinterpret_cast<const unsigned char *>(cJSON_Print((const cJSON*) fHeader.toJSON()));
mbedtls_base64_encode(encodedHeader, 92, &encodedHeaderSize, headerRecast, strlen((const char *) headerRecast));
ESP_LOGI("encodedHeader", "%s", encodedHeader);

// Encode Claim
unsigned char encodedClaim[400];
size_t encodedClaimSize;
const unsigned char* claimRecast = reinterpret_cast<const unsigned char *>(cJSON_Print((const cJSON*) fClaim.toJSON()));
mbedtls_base64_encode(encodedClaim, 400, &encodedClaimSize, claimRecast, strlen((const char *) claimRecast));
ESP_LOGI("encodedClaim", "%s", encodedClaim);

// Concat the header and claim together
std::string headerStr((const char*) encodedHeader);
std::string claimStr((const char*) encodedClaim);
std::string auth = headerStr + "." + claimStr;

// Hash the header.claim
const unsigned char* resultRecast = reinterpret_cast<const unsigned char *>(auth.c_str());
mbedtls_sha256_context shaContext;
unsigned char outHash[32];
mbedtls_sha256_init(&shaContext);
mbedtls_sha256_starts(&shaContext, 0);
mbedtls_sha256_update(&shaContext, resultRecast, strlen((const char *) resultRecast));
mbedtls_sha256_finish(&shaContext, outHash);
mbedtls_sha256_free(&shaContext);
ESP_LOGI("outHash", "%s", outHash);

std::string shaStr;
for (int i=0; i<32; i++) { 
    char str[3];
    sprintf(str, "%02x", (int)outHash[i]);
    shaStr += reinterpret_cast<const char*>(str);
};

// pkcs1_v15_sign sign the hash
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_init( &entropy );
mbedtls_ctr_drbg_init( &ctr_drbg );

mbedtls_pk_context pkContext;
mbedtls_pk_init(&pkContext);
mbedtls_pk_parse_key(
    &pkContext,
    privateKey,
    2000,
    NULL,
    0);
auto rsa = mbedtls_pk_rsa(pkContext);
unsigned char signature[2000];
int res = mbedtls_rsa_rsassa_pkcs1_v15_sign(rsa,
                                    mbedtls_ctr_drbg_random, &ctr_drbg,
                                    MBEDTLS_RSA_PRIVATE,
                                    MBEDTLS_MD_SHA256,
                                    32, reinterpret_cast<const unsigned char*>(shaStr.c_str()),
                                    signature);

// Release Resources
mbedtls_rsa_free( rsa );
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_entropy_free( &entropy );

// Encode Signature
unsigned char encodedSignature[2000];
size_t encodedSignatureSize;
mbedtls_base64_encode(encodedSignature, 2000, &encodedSignatureSize, (const unsigned char*) signature, strlen((const char *) signature));
ESP_LOGI("encodedSignature", "%s", encodedSignature);

// Concat encoded hash.signature
std::string sig((const char*) encodedSignature);
std::string token = shaStr + "." + sig;
return token.c_str();

如果有助于理解我的目标,这是我在Python中做出的概念证明

import requests
from Crypto.Signature import PKCS1_v1_5
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256
from base64 import urlsafe_b64encode, urlsafe_b64decode
import json
import time


now = int(time.time())
header = {"alg": "RS256", "typ": "JWT"}
claim = {
  "iss": "something",
  "scope": "something",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": now + 3600,
  "iat": now
}

key = "{}.{}".format(urlsafe_b64encode(json.dumps(header).encode()).decode(), urlsafe_b64encode(json.dumps(claim).encode()).decode())

with open('key.json', 'r') as f:
    creds = json.load(f)

keyPub = RSA.importKey(creds.get('private_key'))
h = SHA256.new(key.encode())
signer = PKCS1_v1_5.new(keyPub)
signature = signer.sign(h)

key = "{}.{}".format(key, urlsafe_b64encode(signature).decode())
print(key)

I'm a hobbyist and this is my first dive into the world of C++ and embedded systems. I'm struggling a bit with mbedtls.

I'm trying to create a JWT to authenticate against google services. This involves sha256 hashing some base64 encoded json objects (header.claim) and then RSASSA-PKCS1-V1_5-SIGN signing that.

I seem to be ok up to the signing part. My understanding is I can parse the private key with mbedtls_pk_parse_key, and then use that mbedtls_pk_context with mbedtls_rsa_rsassa_pkcs1_v15_sign to sign the hash.

My issue is two fold, I'm not certain I am using mbedtls_rsa_rsassa_pkcs1_v15_sign correctly as the resulting base64 encoded signature comes out as the following in the console. While the encoded json objects are readable.

encodedHeader: ewoJImFsZyI6CSJSUzI1NiIsCgkidHlwIjoJIkpXVCIKfQ==
encodedSignature: ������������������������������������������������������...

Additionally right as this method returns, I get a stack overflow which I am not sure where it's coming from.

***ERROR*** A stack overflow in task main has been detected.


Backtrace:0x40081c0a:0x3ffb82700x40085a4d:0x3ffb8290 0x40088716:0x3ffb82b0 0x4008748f:0x3ffb8330 0x40085b4c:0x3ffb8350 0x40085afe:0x00000000  |<-CORRUPTED




ELF file SHA256: 4307a925ab3c9b48

Here is my code, any help would be greatly appreciated.

// Encode Header
unsigned char encodedHeader[92];
size_t encodedHeaderSize;
const unsigned char* headerRecast = reinterpret_cast<const unsigned char *>(cJSON_Print((const cJSON*) fHeader.toJSON()));
mbedtls_base64_encode(encodedHeader, 92, &encodedHeaderSize, headerRecast, strlen((const char *) headerRecast));
ESP_LOGI("encodedHeader", "%s", encodedHeader);

// Encode Claim
unsigned char encodedClaim[400];
size_t encodedClaimSize;
const unsigned char* claimRecast = reinterpret_cast<const unsigned char *>(cJSON_Print((const cJSON*) fClaim.toJSON()));
mbedtls_base64_encode(encodedClaim, 400, &encodedClaimSize, claimRecast, strlen((const char *) claimRecast));
ESP_LOGI("encodedClaim", "%s", encodedClaim);

// Concat the header and claim together
std::string headerStr((const char*) encodedHeader);
std::string claimStr((const char*) encodedClaim);
std::string auth = headerStr + "." + claimStr;

// Hash the header.claim
const unsigned char* resultRecast = reinterpret_cast<const unsigned char *>(auth.c_str());
mbedtls_sha256_context shaContext;
unsigned char outHash[32];
mbedtls_sha256_init(&shaContext);
mbedtls_sha256_starts(&shaContext, 0);
mbedtls_sha256_update(&shaContext, resultRecast, strlen((const char *) resultRecast));
mbedtls_sha256_finish(&shaContext, outHash);
mbedtls_sha256_free(&shaContext);
ESP_LOGI("outHash", "%s", outHash);

std::string shaStr;
for (int i=0; i<32; i++) { 
    char str[3];
    sprintf(str, "%02x", (int)outHash[i]);
    shaStr += reinterpret_cast<const char*>(str);
};

// pkcs1_v15_sign sign the hash
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_init( &entropy );
mbedtls_ctr_drbg_init( &ctr_drbg );

mbedtls_pk_context pkContext;
mbedtls_pk_init(&pkContext);
mbedtls_pk_parse_key(
    &pkContext,
    privateKey,
    2000,
    NULL,
    0);
auto rsa = mbedtls_pk_rsa(pkContext);
unsigned char signature[2000];
int res = mbedtls_rsa_rsassa_pkcs1_v15_sign(rsa,
                                    mbedtls_ctr_drbg_random, &ctr_drbg,
                                    MBEDTLS_RSA_PRIVATE,
                                    MBEDTLS_MD_SHA256,
                                    32, reinterpret_cast<const unsigned char*>(shaStr.c_str()),
                                    signature);

// Release Resources
mbedtls_rsa_free( rsa );
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_entropy_free( &entropy );

// Encode Signature
unsigned char encodedSignature[2000];
size_t encodedSignatureSize;
mbedtls_base64_encode(encodedSignature, 2000, &encodedSignatureSize, (const unsigned char*) signature, strlen((const char *) signature));
ESP_LOGI("encodedSignature", "%s", encodedSignature);

// Concat encoded hash.signature
std::string sig((const char*) encodedSignature);
std::string token = shaStr + "." + sig;
return token.c_str();

If it helps to understand my goal, here is a proof of concept I made in python

import requests
from Crypto.Signature import PKCS1_v1_5
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256
from base64 import urlsafe_b64encode, urlsafe_b64decode
import json
import time


now = int(time.time())
header = {"alg": "RS256", "typ": "JWT"}
claim = {
  "iss": "something",
  "scope": "something",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": now + 3600,
  "iat": now
}

key = "{}.{}".format(urlsafe_b64encode(json.dumps(header).encode()).decode(), urlsafe_b64encode(json.dumps(claim).encode()).decode())

with open('key.json', 'r') as f:
    creds = json.load(f)

keyPub = RSA.importKey(creds.get('private_key'))
h = SHA256.new(key.encode())
signer = PKCS1_v1_5.new(keyPub)
signature = signer.sign(h)

key = "{}.{}".format(key, urlsafe_b64encode(signature).decode())
print(key)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文