C++实现web token加密生成验证

23 篇文章 0 订阅
17 篇文章 0 订阅
代码 
#include "jwt-cpp/traits/boost-json/traits.h"

#include <boost/json/src.hpp> // You may require this if you are not building it elsewhere
#include <iostream>
#include <sstream>

void testToken() {
	using sec = std::chrono::seconds;
	using min = std::chrono::minutes;
	using traits = jwt::traits::boost_json;
	using claim = jwt::basic_claim<traits>;

	traits::value_type raw_value;
	traits::parse(raw_value, R"##({"api":{"array":[1,2,3],"null":null}})##");
	claim from_raw_json(raw_value);

	claim::set_t list{ "once", "twice" };
	std::vector<int64_t> big_numbers{ 727663072ULL, 770979831ULL, 427239169ULL, 525936436ULL };

	const auto time = jwt::date::clock::now();
	const auto token = jwt::create<traits>()
		.set_type("JWT")
		.set_issuer("auth.mydomain.io")
		.set_audience("mydomain.io")
		.set_issued_at(time)
		.set_not_before(time)
		.set_expires_at(time + min{ 2 } + sec{ 15 })
		.set_payload_claim("boolean", true)
		.set_payload_claim("integer", 12345)
		.set_payload_claim("precision", 12.3456789)
		.set_payload_claim("strings", claim(list))
		.set_payload_claim("array", claim{ big_numbers.begin(), big_numbers.end() })
		.set_payload_claim("object", from_raw_json)
		.sign(jwt::algorithm::none{});
	const auto decoded = jwt::decode<traits>(token);

	for (auto& e : decoded.get_header_json())
		std::cout << e.key() << " = " << e.value() << std::endl;

	const auto array =
		traits::as_array(decoded.get_payload_claim("object").to_json().as_object()["api"].as_object()["array"]);
	std::cout << "payload /object/api/array = " << array << std::endl;

	jwt::verify<traits>()
		.allow_algorithm(jwt::algorithm::none{})
		.with_issuer("auth.mydomain.io")
		.with_audience("mydomain.io")
		.with_claim("object", from_raw_json)
		.verify(decoded);
}

void testTokenES256k() {
	using sec = std::chrono::seconds;
	using min = std::chrono::minutes;
	using traits = jwt::traits::boost_json;
	using claim = jwt::basic_claim<traits>;


	// openssl ecparam -name secp256k1 -genkey -noout -out ec-secp256k1-priv-key.pem
	std::string es256k_priv_key = R"(-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIArnQWnspKtjiVuZuzuZ/l1Uqqq8gb2unLJ/6U/Saf4ioAcGBSuBBAAK
oUQDQgAEfy03KCKUpIPMIJBtIG4xOwGm0Np/yHKaK9EDZi0mZ7VUeeNKq476CU5X
940yusahgneePQrDMF2nWFEtBCOiXQ==
-----END EC PRIVATE KEY-----)";
	// openssl ec -in ec-secp256k1-priv-key.pem -pubout > ec-secp256k1-pub-key.pem
	std::string es256k_pub_key = R"(-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEfy03KCKUpIPMIJBtIG4xOwGm0Np/yHKa
K9EDZi0mZ7VUeeNKq476CU5X940yusahgneePQrDMF2nWFEtBCOiXQ==
-----END PUBLIC KEY-----)";

	traits::value_type raw_value;
	traits::parse(raw_value, R"##({"api":{"array":[1,2,3],"null":null}})##");
	claim from_raw_json(raw_value);

	claim::set_t list{ "once", "twice" };
	std::vector<int64_t> big_numbers{ 727663072ULL, 770979831ULL, 427239169ULL, 525936436ULL };

	const auto time = jwt::date::clock::now();
	const auto token = jwt::create<traits>()
		.set_type("JWT")
		.set_id("rsa-create-example")
		.set_issuer("auth.mydomain.io")
		.set_audience("mydomain.io")
		.set_issued_at(time)
		.set_not_before(time)
		.set_expires_at(time + min{ 2 } + sec{ 15 })
		.set_payload_claim("boolean", true)
		.set_payload_claim("integer", 12345)
		.set_payload_claim("precision", 12.3456789)
		.set_payload_claim("strings", claim(list))
		.set_payload_claim("array", claim{ big_numbers.begin(), big_numbers.end() })
		.set_payload_claim("object", from_raw_json)
		.sign(jwt::algorithm::es256k(es256k_pub_key, es256k_priv_key, "", ""));
	const auto decoded = jwt::decode<traits>(token);

	for (auto& e : decoded.get_header_json())
		std::cout << e.key() << " = " << e.value() << std::endl;

	const auto array =
		traits::as_array(decoded.get_payload_claim("object").to_json().as_object()["api"].as_object()["array"]);
	std::cout << "payload /object/api/array = " << array << std::endl;

	jwt::verify<traits>()
		.allow_algorithm(jwt::algorithm::es256k(es256k_pub_key, es256k_priv_key, "", ""))
		.with_issuer("auth.mydomain.io")
		.with_audience("mydomain.io")
		.with_claim("object", from_raw_json)
		.verify(decoded);
}


void testTokenRS256() {
	using sec = std::chrono::seconds;
	using min = std::chrono::minutes;
	using traits = jwt::traits::boost_json;
	using claim = jwt::basic_claim<traits>;

	std::string rsa_priv_key = R"(-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC4ZtdaIrd1BPIJ
tfnF0TjIK5inQAXZ3XlCrUlJdP+XHwIRxdv1FsN12XyMYO/6ymLmo9ryoQeIrsXB
XYqlET3zfAY+diwCb0HEsVvhisthwMU4gZQu6TYW2s9LnXZB5rVtcBK69hcSlA2k
ZudMZWxZcj0L7KMfO2rIvaHw/qaVOE9j0T257Z8Kp2CLF9MUgX0ObhIsdumFRLaL
DvDUmBPr2zuh/34j2XmWwn1yjN/WvGtdfhXW79Ki1S40HcWnygHgLV8sESFKUxxQ
mKvPUTwDOIwLFL5WtE8Mz7N++kgmDcmWMCHc8kcOIu73Ta/3D4imW7VbKgHZo9+K
3ESFE3RjAgMBAAECggEBAJTEIyjMqUT24G2FKiS1TiHvShBkTlQdoR5xvpZMlYbN
tVWxUmrAGqCQ/TIjYnfpnzCDMLhdwT48Ab6mQJw69MfiXwc1PvwX1e9hRscGul36
ryGPKIVQEBsQG/zc4/L2tZe8ut+qeaK7XuYrPp8bk/X1e9qK5m7j+JpKosNSLgJj
NIbYsBkG2Mlq671irKYj2hVZeaBQmWmZxK4fw0Istz2WfN5nUKUeJhTwpR+JLUg4
ELYYoB7EO0Cej9UBG30hbgu4RyXA+VbptJ+H042K5QJROUbtnLWuuWosZ5ATldwO
u03dIXL0SH0ao5NcWBzxU4F2sBXZRGP2x/jiSLHcqoECgYEA4qD7mXQpu1b8XO8U
6abpKloJCatSAHzjgdR2eRDRx5PMvloipfwqA77pnbjTUFajqWQgOXsDTCjcdQui
wf5XAaWu+TeAVTytLQbSiTsBhrnoqVrr3RoyDQmdnwHT8aCMouOgcC5thP9vQ8Us
rVdjvRRbnJpg3BeSNimH+u9AHgsCgYEA0EzcbOltCWPHRAY7B3Ge/AKBjBQr86Kv
TdpTlxePBDVIlH+BM6oct2gaSZZoHbqPjbq5v7yf0fKVcXE4bSVgqfDJ/sZQu9Lp
PTeV7wkk0OsAMKk7QukEpPno5q6tOTNnFecpUhVLLlqbfqkB2baYYwLJR3IRzboJ
FQbLY93E8gkCgYB+zlC5VlQbbNqcLXJoImqItgQkkuW5PCgYdwcrSov2ve5r/Acz
FNt1aRdSlx4176R3nXyibQA1Vw+ztiUFowiP9WLoM3PtPZwwe4bGHmwGNHPIfwVG
m+exf9XgKKespYbLhc45tuC08DATnXoYK7O1EnUINSFJRS8cezSI5eHcbQKBgQDC
PgqHXZ2aVftqCc1eAaxaIRQhRmY+CgUjumaczRFGwVFveP9I6Gdi+Kca3DE3F9Pq
PKgejo0SwP5vDT+rOGHN14bmGJUMsX9i4MTmZUZ5s8s3lXh3ysfT+GAhTd6nKrIE
kM3Nh6HWFhROptfc6BNusRh1kX/cspDplK5x8EpJ0QKBgQDWFg6S2je0KtbV5PYe
RultUEe2C0jYMDQx+JYxbPmtcopvZQrFEur3WKVuLy5UAy7EBvwMnZwIG7OOohJb
vkSpADK6VPn9lbqq7O8cTedEHttm6otmLt8ZyEl3hZMaL3hbuRj6ysjmoFKx6CrX
rK0/Ikt5ybqUzKCMJZg2VKGTxg==
-----END PRIVATE KEY-----)";

	traits::value_type raw_value;
	traits::parse(raw_value, R"##({"api":{"array":[1,2,3],"null":null}})##");
	claim from_raw_json(raw_value);

	claim::set_t list{ "once", "twice" };
	std::vector<int64_t> big_numbers{ 727663072ULL, 770979831ULL, 427239169ULL, 525936436ULL };

	const auto time = jwt::date::clock::now();
	const auto token = jwt::create<traits>()
		.set_type("JWT")
		.set_id("rsa-create-example")
		.set_issuer("auth.mydomain.io")
		.set_audience("mydomain.io")
		.set_issued_at(time)
		.set_not_before(time)
		.set_expires_at(time + min{ 2 } + sec{ 15 })
		.set_payload_claim("boolean", true)
		.set_payload_claim("integer", 12345)
		.set_payload_claim("precision", 12.3456789)
		.set_payload_claim("strings", claim(list))
		.set_payload_claim("array", claim{ big_numbers.begin(), big_numbers.end() })
		.set_payload_claim("object", from_raw_json)
		.set_payload_claim("sample", claim(std::string{ "test" }))
		.sign(jwt::algorithm::rs256("", rsa_priv_key, "", ""));
	const auto decoded = jwt::decode<traits>(token);

	std::cout << "token: " << token << std::endl;
	for (auto& e : decoded.get_header_json())	// get_payload_json
		std::cout << e.key() << " = " << e.value() << std::endl;

	std::string rsa_pub_key = R"(-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuGbXWiK3dQTyCbX5xdE4
yCuYp0AF2d15Qq1JSXT/lx8CEcXb9RbDddl8jGDv+spi5qPa8qEHiK7FwV2KpRE9
83wGPnYsAm9BxLFb4YrLYcDFOIGULuk2FtrPS512Qea1bXASuvYXEpQNpGbnTGVs
WXI9C+yjHztqyL2h8P6mlThPY9E9ue2fCqdgixfTFIF9Dm4SLHbphUS2iw7w1JgT
69s7of9+I9l5lsJ9cozf1rxrXX4V1u/SotUuNB3Fp8oB4C1fLBEhSlMcUJirz1E8
AziMCxS+VrRPDM+zfvpIJg3JljAh3PJHDiLu902v9w+Iplu1WyoB2aPfitxEhRN0
YwIDAQAB
-----END PUBLIC KEY-----)";

	const auto array =
		traits::as_array(decoded.get_payload_claim("object").to_json().as_object()["api"].as_object()["array"]);
	std::cout << "payload /object/api/array = " << array << std::endl;;

	jwt::verify<traits>()
		.allow_algorithm(jwt::algorithm::rs256(rsa_pub_key, "", "", ""))
		.with_issuer("auth.mydomain.io")
		.with_audience("mydomain.io")
		.with_claim("object", from_raw_json)
		.verify(decoded);
}

int test() {
	testToken();	// token有效验证
	testTokenES256k(); // token加密验证,依赖openssl
	testTokenRS256();
	return 0;
}
输出

    
    typ = "JWT"
    alg = "none"
    payload /object/api/array = [1,2,3]
    
    
    typ = "JWT"
    alg = "ES256K"
    payload /object/api/array = [1,2,3]
    
    
    token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJhdXRoLm15ZG9tYWluLmlvIiwiYXVkIjoibXlkb21haW4uaW8iLCJpYXQiOjE3MjQxMzY1NzMsIm5iZiI6MTcyNDEzNjU3MywiZXhwIjoxNzI0MTM2NzA4LCJib29sZWFuIjp0cnVlLCJpbnRlZ2VyIjoxMjM0NSwicHJlY2lzaW9uIjoxLjIzNDU2Nzg5RTEsInN0cmluZ3MiOlsib25jZSIsInR3aWNlIl0sImFycmF5IjpbNzI3NjYzMDcyLDc3MDk3OTgzMSw0MjcyMzkxNjksNTI1OTM2NDM2XSwib2JqZWN0Ijp7ImFwaSI6eyJhcnJheSI6WzEsMiwzXSwibnVsbCI6bnVsbH19fQ.abnNu6Cw15Bhw-KSyLRyNoczx277lC8X0T2qipZ6zujh_EWGZXzVqIkdgSPrXAmuC9fbOEgdgKoLGSTNvkw4iFX6bql8qcde91rr5wYtp_EnjMk8xM_Ootp6ETO5fF8jZSNdEWWLVpZQxFIm_IFogjbTAzySP4ZuQC1B4Gf_qVM0XAJMG1fW7Hwl_6VtW_SfXf9JEKrJB7d-Tex3aTm-BfRqKIQl0GclWuZtfmvvRmJuMpTr4OqhM7w8FDbavsbjvbNNZyr2tH5P0k8Zm6BWgjAD5y4vlsp0drb_NIaVay5J3VxhGnQ-aReVBfi_N3sbJrLF6vpruEwCnu084P4a-A
    typ = "JWT"
    alg = "RS256"
    payload /object/api/array = [1,2,3]
    

参考 

GitHub - Thalhammer/jwt-cpp: A header only library for creating and validating json web tokens in c++

MICROSOFT FOUNDATION CLASS LIBRARY : ZSCPascal AppWizard has created this ZSCPascal application for you. This application not only demonstrates the basics of using the Microsoft Foundation classes but is also a starting point for writing your application. This file contains a summary of what you will find in each of the files that make up your ZSCPascal application. ZSCPascal.h This is the main header file for the application. It includes other project specific headers (including Resource.h) and declares the CZSCPascalApp application class. ZSCPascal.cpp This is the main application source file that contains the application class CZSCPascalApp. ZSCPascal.rc This is a listing of all of the Microsoft Windows resources that the program uses. It includes the icons, bitmaps, and cursors that are stored in the RES subdirectory. This file can be directly edited in Microsoft Developer Studio. resSCPascal.ico This is an icon file, which is used as the application s icon. This icon is included by the main resource file ZSCPascal.rc. resSCPascal.rc2 This file contains resources that are not edited by Microsoft Developer Studio. You should place all resources not editable by the resource editor in this file. ZSCPascal.reg This is an example .REG file that shows you the kind of registration settings the framework will set for you. You can use this as a .REG file to go along with your application or just delete it and rely on the default RegisterShellFileTypes registration. ZSCPascal.clw This file contains information used by ClassWizard to edit existing classes or add new classes. ClassWizard also uses this file to store information needed to create and edit message maps and dialog data maps and to create prototype member functions. For the main frame window: MainFrm.h, MainFrm.cpp These files contain the frame class CMainFrame, which is derived from CMDIFrameWnd and controls all MDI frame features. resToolbar.bmp This bitmap file is used to create tiled images for the toolbar. The initial toolbar and status bar are constructed in the CMainFrame class. Edit this toolbar bitmap along with the array in MainFrm.cpp to add more toolbar buttons. AppWizard creates one document type and one view: ZSCPascalDoc.h, ZSCPascalDoc.cpp - the document These files contain your CZSCPascalDoc class. Edit these files to add your special document data and to implement file saving and loading (via CZSCPascalDoc::Serialize). ZSCPascalView.h, ZSCPascalView.cpp - the view of the document These files contain your CZSCPascalView class. CZSCPascalView objects are used to view CZSCPascalDoc objects. resSCPascalDoc.ico This is an icon file, which is used as the icon for MDI child windows for the CZSCPascalDoc class. This icon is included by the main resource file ZSCPascal.rc. Other standard files: StdAfx.h, StdAfx.cpp These files are used to build a precompiled header (PCH) file named ZSCPascal.pch and a precompiled types file named StdAfx.obj. Resource.h This is the standard header file, which defines new resource IDs. Microsoft Developer Studio reads and updates this file. Other notes: AppWizard uses "TODO:" to indicate parts of the source code you should add to or customize. If your application uses MFC in a shared DLL, and your application is in a language other than the operating system s current language, you will need to copy the corresponding localized resources MFC40XXX.DLL from the Microsoft Visual C++ CD-ROM onto the system or system32 directory, and rename it to be MFCLOC.DLL. ("XXX" stands for the language abbreviation. For example, MFC40DEU.DLL contains resources translated to German.) If you don t do this, some of the UI elements of your application will remain in the language of the operating system.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码力码力我爱你

创作不易,小小的支持一下吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值