Thalhammer / jwt-cpp

A header only library for creating and validating json web tokens in c++
https://thalhammer.github.io/jwt-cpp/
MIT License
917 stars 243 forks source link

Support OpenSSL 1.0.2 RSA key with passphrase's non standard format #359

Open agurianov opened 3 months ago

agurianov commented 3 months ago

What happened?

I'm using rsa key with passphrase. When I construct jwt::algorithm::rs256 I've got an exception: failed to load key: bio read failed

How To Reproduce?

#include "jwt-cpp/jwt.h"
int main() {
            std::string rsa_priv_key = R"(-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,4F64EDF65583E1AF7D45853FAAD9C3D6

iVKXcShgXh6uvbN/UWd+a5fjEIJtLDJKhlDbHwpZ95hIODwD1KxQt/vviJRIMGhi
xBoVXlqlz/Miy2aawduD5zCLRpE0JXZb2R4YsQVje43k59wY/02fmrunFChVNU1P
mPfldB8UiLM3GDUKzsKyawf2YEVDQPi8hlt7GxME1wYPL5/tVq2URT52AcdwtMWW
xT3jac0Ana2sS5oevz8JRA4za/VEHE2M8GCchxWq6RM1+Gq5wdbNkdk+DdBx9fWJ
vgWkyZdb6Rb7O+upFvf/Hfg0QjMEPW3yUfuDPNHQ7k0AYmw8lYiN59HmaXRZMNgC
cmsWUWX9vVddoT++wXSiMKn/mUvBWxV5W7H0LMDVoLtki6yQiA4TY5glhJeT/y/w
c5KpntdsLvXfwOddhx9Bib3TFDYmj1hI3oBMkE9INHhL6GLv6TdWsasy8PoHJZ8p
00gporw9USQub73jrkLZ4oQosDOR1TRl93STkitHweBXT/VVQBO4SQ5BPqeD9D6C
bU0nlhQKNqFseihaUscFVOB0wdTkhFmeOz9XoIsZsMIurqIUhGA6o5pOQ1/ofU/Q
Wtuc75qvMNPiTrd0lNMLIHlfpQgjErOwnyJr2E8MjbuQptA93QzOiG7di+5aOBFN
9hPmeO1JaGQllqwa+CxO1CFu28O8TaGH9tyll+OUgLAqUHVQeo2yd0+76ruheO3z
6kgvDGnXiu5dUqTs6LfgSNNjtcJGke5Gn6qz/YB2jXu88CTZgef8RciISAIeI/XI
0Kj69Ojd9AHMvPwxgW1GfPtFVAB2I6a5xiaDppCjzst3otnDrz96Ck9gPvOg4R2e
7wYFc0A/bJTcVz4n5DH9em/dtfugiDE4JzZkbJu0FLR1u5+Fkdj/wujZAuklgEOC
tiQrkSuSz1xetDCh3EvjVfqW5OigyxrrTnQ93whlzJgAPtq6XUkBIL7S/8bJDmJv
A1I+yf9KTuBAFEc13eCFN3eQ71E+2UUGrgJQmBaZORd65/bFAeiIfZeF7HNlGlnT
xJVFFdCdnf/+1koyCwkF2Px27DOSbYvvIEbGs6K8IFDoI21I2uMkk6JOWg06wK/P
D3v13wMWippA0Lq84NwELFy8mdAmyzlUEjE7feJiWafG9gwKuiaYin3eIyVFhQCI
lHdKw1rWVgYjOVFmpGziqkLm3DtTekg9VqxUR+FWkvbdiHyu89dV1bt4D4WiJbkk
JbIzrsmOBXjyZDQJ75KTXCAlZcrTvyi0ICyAz8vr7TPxo0yBJh7gxAjUxeAKuExx
knu65jUjCAhlaJgcGViCe+0QyZhReASFjpg/RdhqUJOja2oTnne8mxl2AjARS9Wg
yscVFb8U64sVDPLwJQQ1AfNNcI5kekOX57O9uHpotgA65a9drfdr69TLCxHEvZFa
lvnktXralWsBnXUhkM7DwuzKJ1dDUxD/E/JnPq1PtuPITZ72tIFHVV4MSGghP43x
20WwTT4uRwtQUBmplYBy+kDzgcwbaxD+1NqniG8M73Lcym3WDmKHgXl6uWCDWFg5
KpKs6kL/LVEeFXd8pa+695FDPUCZThoI6JCizxr2vhvjh2EacZJIyhfIInf1Ek+G
-----END RSA PRIVATE KEY-----
)";
   const jwt::algorithm::rs256 rs("", rsa_priv_key,"","12345678");
   return 0;
}

Version

0.7.0

What OS are you seeing the problem on?

Linux

What compiler are you seeing the problem on?

GCC

Relevant log output

No response

Code of Conduct

prince-chrismc commented 3 months ago

Could you please share how you generate the private key? 🙏

agurianov commented 3 months ago

[alex@S2T ~]$ ssh-keygen -f 2.txt Generating public/private rsa key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in 2.txt. Your public key has been saved in 2.txt.pub. The key fingerprint is: SHA256:iSsLk6KhXwvCTPL9Ru24VNnT7EmEsXKzrgjeoVmmKDA alex@S2T The key's randomart image is: +---[RSA 2048]----+ | . | | + | | . = . | | . | |.. ..S + + | |E. o .o.. + . | |=+ =.o . o | |++ B #oo.. | |ooo B.=.. | +----[SHA256]-----+ [alex@S2T ~]$ cat 2.txt -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,798F5275AC2E046DC7E6FDB7CB0FD3C4

uPYAgVjjzxYjKbw924vlDyF+/bbggY7aP9Lwsw5hBFMhSlIVUs80P1a0FfNDlG8c Lbt//p1pPz/Y2nhvxG7JB2lHjRF+OBbQEckOHahGnhEX3X37BYGDSzo5KUm1K0MV G7Z9UbKkLuEJ8/fb0a3/HACR6pyHym1nqvVbb3q32Pe735zbsYvFpmwBDJFOMXfb nLy++U7XsUGcbhAsBOZ6EWM0mxPFVLup1aiYhT2hS9bDW49n31v4DsSp9x+vnqtO 5nmm4/U3SGYEKIaMlHplS6BNCUvUkcyABk5YSs/iO8tuNGwaX6HbJuHnr7VIOnHx 2ESw+ss1kyB8cBV9K9oXViaUJcofjvPQBWRZUW+yTinHpb7Enx+ckCIH3EdTYP4U od0AlqtwmC7cdX0/eJJkKJM/sGu3wg8pHhN/O109/o8LRk4L7o1H8DOtzp4Yw9Ha 2cTnea/sWYSnmJMPG0LebthWC5+wn7WwuO28BADNjTqGxnII6GIdeTXeHkUcliVn LJeOKMRSV4lgat9PD8CvGFzX3SN6/j+XjEPovvZeeQxFJ1/qXt8thjE8GzBTGwlj FiO8xXKyKvf6k4XqdYvkPD3oRqAuZfBKNpzoZVlYW15fubQDdsQMAfiGCHRcKXrm HlL7WQvmLwHxdcvJomm/FkNnd1gDhqNUBtESTI1uo+AvYhiuqJ3UlJQ6tx3kaDVB DQ/vyUHsxjYTLWtpKt9fC/jX2782ecZ+H2jKSjRDmrSjjFfDKTdisn6yjgoipWgN MKu5/o32vqlyQBKoAnL64KBdch39ASUeXDIkPKCq+eTLOaPBJCWdY2zFK2lToxfw YCpQnbwWPb9tLwBwsAi1XLsH2NJ7uHAmpOYvBcaq01Zw5tiys2Y1zcTt2S5DXRm1 UkTvYjCA0AOTrVJDr/6OVWvomIa791TCzPw/8c2OdiXKqqE9Fpcdj2S8NY8mWKTM +dhsSE1VAONx8t4XoBQHbiUJhNw23Ce+YZOxZl9SVzG4IobOymTKcRZHyw1E4I5s 1QQCWTdtbyfUwu5O7nFVcHMOnyTfiLMsUih2+NWfqLBWbtkB3rK/hEmAk2xU7WYU spLJnqWoGaaT29nDuK/aek2Ynd56MqZqVDK6MuIZtajeMxi89jXm3D+NhFuNNi9H Qn/l00ECDyN4ODnREFp32nCqF2FiJ+C9fofnu6QVTOpnmvWYKRsxKvRcgdzgNbnm qWcDsXXcDJz846ANWF01RPnEWdSBVtnw6n12/SBscgP7lOBeWbiTU5dyO4MXlb9w jlW6I7DaE+7G2/JZ36BHdl8bzndRr4Z2pSlLunTewNU3K3dhsQD7dfuNxVqOqRep 3qTWMpPCgknxNrtIMfP5vR44Lx9pWIciZlfS11Cz6qFua6ZjP7E9B9a7/kzgKi7l nuBT0mUCj1sBh5HQmqpEv0cSTIQx8sv5x6Zx1KKvXynTvnthNAK87IK1JNDEXsCg 0nFOMFb7XxCxi1TNJBnmQCdlMmYV5YK1LuM3mssSkGVqqp3wC83GJrxDVFj5NCIT HqD53RYPxGRk0ZM2ZXT3gV+2W+9YGRrGG2VOZPi//J6n6532HhnDjbCBH0y/72K8 -----END RSA PRIVATE KEY-----

prince-chrismc commented 3 months ago

SSH Keys are not always compatible with openssl they generally have something other then the PCKS8 format https://github.com/Thalhammer/jwt-cpp/issues/241 for more context.

I was able to get this to work making the key with openssl, you can see #360 for the CLI I used

agurianov commented 2 months ago

I've tried the keys from the test and am still having the issue. I've noticed this phrase in the comment : "disable 1.0.2". Does it mean that openssl 1.0.2 has some knonw issues? I have OpenSSL 1.0.2k-fips. My version of openssl generates keys like this: -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-256-CBC,B6445B73CFD47418AEB9013C68885F01

ImSmKFFN18D5eI5GCEQFTVqpPs/NUjMq0/o6b+EZBeFvMYO18oLZltrduS8LeFmq NxEDY/ZZK6YPE22cMU77poL8wUe6mP+210sCBz1C+PzU+MHqkaLgVExv5kDcSfmD 8Rjm9nSM/DOYj1xr0zwBus+sfY+VE0qMe/3iCwVkGWlRUApbIjI/sYDSVnHQ9rHN u0Pz1WxFOwIqQMot6JUGkFsVFmg8wUAE4h9quP6piPP09fys5KnGNoB/QQHOZDXh mV3VRaE6l1TU/qPK+vFxwa5gQFs2szOvoEUSUIRCQyT+b8bmCvCpYXmVv9836+rM tFmOrQCSsl5cIHiJZcJnMKPY30cC6/bMzi1lMdYeW/SJ06EjKdp7bf+esMJ0L0/B LWcg3s+lT451fXj0M8wUkRZJxaynX8YXuVCVShKhDAlbnkpuH64b79CTivtJ7LR1 W2jSkGxJ0PcKknlTfTXdQ2tJBUm4KVHHsuyTZ/3eWFE2UJxaSeiNp0+vm3PhbLDq y9y+uzclKerLeV/PRPe2BV9MycwQSroLPzu939EdO1heVI47v1XHvYPky7STZVgn VYMDU4ZDDXTx+5C9VRBhwpB8a6orzyT5VSMw8D2n1y8UVzUzMPfHEzNjIA6AuoKO 9pXk9oGeA8zkm6i4Thkwu9+kqcl0q9PPiXRFItcom29s2gZrCXjBEPFtDpEC/FvT 2+XILRfKHbgarTstF5eVUsz5Y/B25+fsoHAfMmTe2OEC9E5Lxn9vdk/7PTEkgvUI v9KE69Qf5zAiIPQt3F0Y21L9i3ra4UIXmwko/NKz1K4ozkC+LNC/Dn/Y0I3fp9yj x+knMfnJMTegGHR90yx1ttCDNgsbqNqYaS11eVY4fzcaIdlTc67/ePFJtPrOUGHN HXMWm6I65lT3/r203+As0w6nRc4OKE0uOTIEcKkrRM3fsPeav2ldfT6fot1MD4Ni ZGZcfMmjXXuy9SAEofF2mRg4wxqC8GYfkZv5pk7KbMIXhyNwrEG0y4Nh8w+9aGBH /wBfaIgT7iZmUQJGW+F4U1snh7WqJ5HBuDOOk1WYjqOVUMtGmcS8vP75ga1vkrUt uTEXN344ciQiiwwjntohBDbgcG0fq2HP1I5jJzR8SfigIqwnQ3UKPDL6Oa/0Dm/L aT34MvIOgZLCFfso/BTd6JOuj80IR25DQYOOrLE+Fm6D2BSV/XDDskypYWlOSJf4 sQBs33r84FIWkgU7s2c2zs6K+cO2bcd80fISQ79UVv7NVwDoi7bEL6G6jOJguFdj WTwlDxsdwG15X8wd9i5dudp6pzxOKVH0CvhJBIIMx6BHd6RqsAwbY3lwLlMBUIzs e0KUiGzxz7ouqUR37PbVPxZe2QM20wtBLW3nHz/VtdHNqaxHN8BQyQ71AsRNuT2p HYaU2905iYxxFmiZ1Ex0GwN1ownH1p2D/5MH6Lo3QzhDWK4UxbbQ7kJLi+z6POUh Uq356loEMPremZuhdReMOSmzKOSPN1YAAHFDOhszynyxyNbQ+bZV1/MWrq7cxlcr mMLOnssNGZMgyD0eJey9voJbgRUimP7uW68tDCE+R2QYF9KD587EuOF2Vlx+EVdk -----END RSA PRIVATE KEY-----

prince-chrismc commented 2 months ago

~I've not found a very assuring answer.~ This does not look like a PCKS #8 format because it has PBES2 which was more common with PKCS #5, found this period example showing the difference .... to my knowledge the older version of OpenSSL is running that old version by default.

These old PrivateKey routines use a non standard technique for encryption. The private key (or other data) takes the following form: -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,3F17F5316E2BAC89
...base64 encoded data... -----END RSA PRIVATE KEY-----

https://docs.openssl.org/3.1/man3/PEM_read_bio_PrivateKey/#pem-encryption-format

https://crypto.stackexchange.com/a/40293 there's also new options for openssl v3

prince-chrismc commented 2 months ago

Going to make this as an enhancement since it was never support 🙊 if you'd like to contribute the implementation that would be more then welcome :)