Tôi là lập trình viên C++ khá mới (tôi vẫn còn ở trường đại học nên tôi cho rằng tôi là một lập trình viên khá mới) và tôi đang cố gắng tạo ra JWT trong C++. Tôi có thể tạo ra và mã hóa một tiêu đề và tải trọng, nhưng chữ ký tôi tạo ra bằng cách sử dụng thư viện hmac openssl có vẻ là không hợp lệ khi tôi kiểm tra nó trên jwt.io. Tôi có một cảm giác này là do một số sai lầm sắc thái tôi chỉ không nhìn thấy. Nếu bạn có thể tìm thấy lỗi của tôi, tôi sẽ đánh giá cao nó. Nếu bạn cũng có đề xuất về cách cải thiện mã của tôi nói chung cũng sẽ được đánh giá cao. Lưu ý tôi phải sử dụng openssl và boost cho json.JWT (Mã thông báo Web JSON) bằng C++ sử dụng lỗi tăng và lỗi mở
**** CẬP NHẬT ****
tôi phát hiện ra rằng thêm dòng mới đã được bổ sung và điều này gây ra sai sót trong quá xác thực. Hiện nay tôi đang kêu gọi str.erase để loại bỏ chúng nhưng nếu ai đó có thể cho tôi biết nơi họ đang đến tôi sẽ đánh giá cao nó vì vậy tôi có thể tránh được việc phải thao tác chuỗi
char* Auth::genJWT()
{
ptree pt;
std::stringstream jwt;
//Make and encode header
pt.put("typ","JWT");
pt.put("alg","HS256");
std::ostringstream buf;
write_json(buf, pt, false);
std::string header = buf.str();
jwt << base64_encode((unsigned char*)header.c_str(), (int) header.length());
//clear buffer
pt.clear();
buf.clear();
buf.str("");
//make pay load
pt.put("org_guid", Config::organization_guid);
pt.put("agent_guid", Config::agent_guid);
write_json(buf, pt, false);
std::string payload = buf.str();
jwt << '.' << base64_encode((unsigned char*)payload.c_str(), (int) payload.length());
//sign data
std::string signed_data = signToken(jwt.str());
jwt << '.' << base64_encode((unsigned char*) signed_data.c_str(), (int) signed_data.length());
//jwt made
std::cout << "JWT Token: " << jwt.str() << std::endl;
//Note I am testing by copying the token into an online debugger
//returning "" is not my bug
return "";
}
Đây là phương pháp tôi sử dụng ký token
std::string Auth::signToken(std::string to_sign)
{
//std::string key = Config::secret;
std::string key = "foo";
unsigned int len = 32;
unsigned char signed_data[32];
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, &key[0], (int) key.length(), EVP_sha256(), NULL);
HMAC_Update(&ctx, (unsigned char*)&to_sign[0], to_sign.length());
HMAC_Final(&ctx, signed_data, &len);
HMAC_CTX_cleanup(&ctx);
std::stringstream ss;
ss << std::setfill('0');
for(unsigned int i = 0; i < len; i++)
{
ss << signed_data[i];
}
return (ss.str());
}
Đây là cách tôi mã hóa dữ liệu trong base64Url
std::string Auth::base64_encode(const unsigned char* input, int length)
{
BIO *bmem, *b64;
BUF_MEM *bptr;
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, input, length);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
std::stringstream ss;
//make URL safe
for(unsigned int i = 0; i < bptr->length - 1; i++)
{
switch(bptr->data[i])
{
case '+':
ss << '_';
break;
case '/':
ss << '-';
break;
case '=':
//don't add in padding
break;
default:
ss << bptr->data[i];
break;
}
}
BIO_free_all(b64);
return (ss.str());
}