FredericJacobs / OpenSSL-Pod

Unmaintained - please fork. Email me to take over the CocoaPod
74 stars 112 forks source link

Problem in a private key conversion from JWK to PEM formats #48

Open elenatorroglosa opened 6 years ago

elenatorroglosa commented 6 years ago

Hello,

I'm trying to convert a private key from JWK format (JSON) to PEM format using the openSSL library. My problem is an error in the result since it has an invalid format when I try to check the result with the openssl command line tool. I don't know if I have to ask here or in the official/original openssl repo, but maybe someone can give some guide to solve the error.

The JWK used is the following:

jwk = { "p": "yZnnC4tGxAeu7G-N-zxb8dOpHrk88VsXRoNH1sj54CIwj-y77amx4J6WCw_y7A9L_K3Fpn3Cbje5MNQJlizDLg8NdKWfC2yntkZD8SVEbU1EshDj8tWhMZSkKp3P7KM1ht1b8Okban9QNSnx-2y7Emtd2x78zjAFJt66yJGSx_k", "d": "KzmTm_rtw555d5ztEocm5Jb2gxDucsLLecWbDTlDZuJqifLVhrmhw8k9Pvenl5aw4jBBZmS2IDbc3uF5gs1gtujcELSPcJ__12ed4-vexWEkGdqNWSMvxwfvXrU5Gv_08Hj6zbORMt9OzvYdbRJrhv0UOJ4wvWSrQ_BrEPG4FXcJKuTFvQ4n2lckacmXlAgyZmAdeldU6C9s-st-vfJ25OabFVo8FyP7pa92KS-EgDTUTUJXqczNHYJbfWKVbAs9nBnDnU3ulE2pm48LHbgqeS2tejvIIIZ47bGRWudgbpeFamXPEf0Ow3AYNntTXCpKKdRN--XK5vAx2riw7LuWuQ", "q": "1xZNBiXqqgNuMNyw8YqS4ByN57XD00E9LH_HU54eL6sCkU6DM7Echpy2k5rIi6rs1_HxjS9pOcepqV4LE-0Q0_rwjGz7xWtZy0pCN1-nxWcHtC-BriBr2UE2_4VYIIo-UYVT3Vbyx8jyIWfJ_a4wiE083nGjf3OPvFP9ptZY_wM", "n": "qWHQ7K7sVNWb4QZe2TFdDeOH3zwYVU8aGWkh9KmUSadpBLpWheg0jhAx9v9-67cN-yJxHM02SOQmghk3aFKG_u39tm3rxGLrlEMIirUTY9Z60oaM9NOV9Q0Z5sSdNILfeMcZ01MrHlqJC_IjTPANPyhn3i2W4ZlgnmQLvvUvpUDwYexOB33e_DZf64OW7DOjh2qlNhTYxxo3fKJAA-C_dCL5IHL5TWYHrlULO7bVIisflUNjhyfEWcfRB8_XfN2-2NcBawp-OIbzPpik3mVNKuIYcf7JjVKgcJP7DYvzCGyoplTQOrcekSIO6UhXqc4Dd8tn0lXRIPBV1ndvzYFe6w", "kid": "DIEalhwEKmalZljtgVHdWqobAnBhLpjnMdGw9yFNNEs", "kty": "RSA", "use": "sig", "e": "AQAB" }

And this is the method that I have implemented to do the conversion:

` +(NSString ) convertFromJWKtoPEM_PrivateKey: (NSDictionary )jwk passphrase:(NSString *)passphrase {

NSLog(@"- starting convertFromJWKtoPEM_PrivateKey");
RSA * rsaKey = RSA_new();

ENGINE * rsaEngine = ENGINE_new();
//ENGINE_get_default_RSA();
int eng_init_result = ENGINE_init(rsaEngine);
if (eng_init_result == 0)
    NSLog(@"Error initializing the rsaEngine");

rsaKey->engine = rsaEngine;

BIGNUM *n_bn = NULL, *e_bn = NULL;
BIGNUM *d_bn = NULL, *p_bn = NULL, *q_bn = NULL;

e_bn = BN_new();
n_bn = BN_new();
d_bn = BN_new();
p_bn = BN_new();
q_bn = BN_new();

NSString * ezu = [jwk objectForKey:@"e"]; // public exponent
NSString * nzu = [jwk objectForKey:@"n"]; // public modulus
NSString * dzu = [jwk objectForKey:@"d"]; // private exponent
NSString * pzu = [jwk objectForKey:@"p"]; // secret prime factor
NSString * qzu = [jwk objectForKey:@"q"]; // secret prime factor

NSString *nz = [MF_Base64Codec base64StringFromBase64UrlEncodedString:nzu];
NSData *nn = [[NSData alloc]
              initWithBase64EncodedString:nz
              options:0];

NSString *ez = [MF_Base64Codec base64StringFromBase64UrlEncodedString:ezu];
NSData *en = [[NSData alloc]
              initWithBase64EncodedString:ez
              options:0];

NSString *dz = [MF_Base64Codec base64StringFromBase64UrlEncodedString:dzu];
NSData *dn = [[NSData alloc]
              initWithBase64EncodedString:dz
              options:0];

NSString *pz = [MF_Base64Codec base64StringFromBase64UrlEncodedString:pzu];
NSData *pn = [[NSData alloc]
              initWithBase64EncodedString:pz
              options:0];

NSString *qz = [MF_Base64Codec base64StringFromBase64UrlEncodedString:qzu];
NSData *qn = [[NSData alloc]
              initWithBase64EncodedString:qz
              options:0];

NSString * ehexString = [self NSDataToHex:en];
NSString * nhexString = [self NSDataToHex:nn];
NSString * dhexString = [self NSDataToHex:dn];
NSString * phexString = [self NSDataToHex:pn];
NSString * qhexString = [self NSDataToHex:qn];

NSLog(@"load param n: \n%@", nz);
NSLog(@"load param e: \n%@", ez);
NSLog(@"load param d: \n%@", dz);
NSLog(@"load param d: \n%@", pz);
NSLog(@"load param d: \n%@", qz);
NSLog(@"nn converted from b64urlformat: %@", nn.debugDescription);
NSLog(@"en converted from b64urlformat: %@", en.debugDescription);
NSLog(@"dn converted from b64urlformat: %@", dn.debugDescription);
NSLog(@"pn converted from b64urlformat: %@", pn.debugDescription);
NSLog(@"qn converted from b64urlformat: %@", qn.debugDescription);
NSLog(@"en converted to hexadecimal: %@", ehexString);
NSLog(@"nn converted to hexadecimal: %@", nhexString);
NSLog(@"dn converted to hexadecimal: %@", dhexString);
NSLog(@"pn converted to hexadecimal: %@", phexString);
NSLog(@"qn converted to hexadecimal: %@", qhexString);

const char *e_char = [ehexString UTF8String];
const char *n_char = [nhexString UTF8String];
const char *d_char = [dhexString UTF8String];
const char *p_char = [phexString UTF8String];
const char *q_char = [qhexString UTF8String];

//int BN_hex2bn(BIGNUM **a, const char *str);
int res1 = BN_hex2bn(&e_bn, e_char);
int res2 = BN_hex2bn(&n_bn, n_char);
int res3 = BN_hex2bn(&d_bn, d_char);
int res4 = BN_hex2bn(&p_bn, p_char);
int res5 = BN_hex2bn(&q_bn, q_char);

rsaKey->e = e_bn;
rsaKey->n = n_bn;
rsaKey->d = d_bn;
rsaKey->p = p_bn;
rsaKey->q = q_bn;

////////// DEBUG //////////
NSString * tmpRSAFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent: [NSString stringWithFormat: @"%.0f.%@", [NSDate timeIntervalSinceReferenceDate] * 1000.0, @"txt"]];
FILE *tmpRSAFile = fopen([tmpRSAFilePath cStringUsingEncoding:NSUTF8StringEncoding], "w+");

int rsa_print = RSA_print_fp(tmpRSAFile, rsaKey, 0);
fclose(tmpRSAFile);
NSString * fileContents = [NSString stringWithContentsOfFile:tmpRSAFilePath encoding:NSUTF8StringEncoding error:nil];
NSLog(@"RSA_print_fp:\n%@", fileContents);
/////////////////

NSString * tmpPEMFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent: [NSString stringWithFormat: @"%.0f.%@", [NSDate timeIntervalSinceReferenceDate] * 1000.0, @"txt"]];
FILE *tmpPEMFile = fopen([tmpPEMFilePath cStringUsingEncoding:NSUTF8StringEncoding], "w+");
int res_conversion = PEM_write_RSAPrivateKey(tmpPEMFile, rsaKey, nil, nil, 0, nil, nil);
fclose(tmpPEMFile);
NSLog(@"Conversion result form RSA to PEM (private key): %d", res_conversion);

// read the contents into a string
NSString *pemStr = [[NSString alloc]initWithContentsOfFile:tmpPEMFilePath encoding:NSUTF8StringEncoding error:nil];
NSLog(@ PEM Private String content:\n%@", pemStr);

NSString *pem1 = [pemStr componentsSeparatedByString:@"-----END RSA PRIVATE KEY-----"][0];
//NSLog(@"PEM String content1:\n%@", pem1);
NSString * pemResult = [pem1 componentsSeparatedByString:@"-----BEGIN RSA PRIVATE KEY-----\n"][1];
NSLog(@"PEM Private String result:\n%@", pemResult);

ENGINE_finish(rsaEngine); RSA_free(rsaKey);

return pemResult; 

} `

This is the PEM result: -----BEGIN RSA PRIVATE KEY----- MIIDGQIBAAKCAQEAqWHQ7K7sVNWb4QZe2TFdDeOH3zwYVU8aGWkh9KmUSadpBLpW heg0jhAx9v9+67cN+yJxHM02SOQmghk3aFKG/u39tm3rxGLrlEMIirUTY9Z60oaM 9NOV9Q0Z5sSdNILfeMcZ01MrHlqJC/IjTPANPyhn3i2W4ZlgnmQLvvUvpUDwYexO B33e/DZf64OW7DOjh2qlNhTYxxo3fKJAA+C/dCL5IHL5TWYHrlULO7bVIisflUNj hyfEWcfRB8/XfN2+2NcBawp+OIbzPpik3mVNKuIYcf7JjVKgcJP7DYvzCGyoplTQ OrcekSIO6UhXqc4Dd8tn0lXRIPBV1ndvzYFe6wIDAQABAoIBACs5k5v67cOeeXec 7RKHJuSW9oMQ7nLCy3nFmw05Q2biaony1Ya5ocPJPT73p5eWsOIwQWZktiA23N7h eYLNYLbo3BC0j3Cf/9dnnePr3sVhJBnajVkjL8cH7161ORr/9PB4+s2zkTLfTs72 HW0Sa4b9FDieML1kq0PwaxDxuBV3CSrkxb0OJ9pXJGnJl5QIMmZgHXpXVOgvbPrL fr3yduTmmxVaPBcj+6WvdikvhIA01E1CV6nMzR2CW31ilWwLPZwZw51N7pRNqZuP Cx24KnktrXo7yCCGeO2xkVrnYG6XhWplzxH9DsNwGDZ7U1wqSinUTfvlyubwMdq4 sOy7lrkCgYEAyZnnC4tGxAeu7G+N+zxb8dOpHrk88VsXRoNH1sj54CIwj+y77amx 4J6WCw/y7A9L/K3Fpn3Cbje5MNQJlizDLg8NdKWfC2yntkZD8SVEbU1EshDj8tWh MZSkKp3P7KM1ht1b8Okban9QNSnx+2y7Emtd2x78zjAFJt66yJGSx/kCgYEA1xZN BiXqqgNuMNyw8YqS4ByN57XD00E9LH/HU54eL6sCkU6DM7Echpy2k5rIi6rs1/Hx jS9pOcepqV4LE+0Q0/rwjGz7xWtZy0pCN1+nxWcHtC+BriBr2UE2/4VYIIo+UYVT 3Vbyx8jyIWfJ/a4wiE083nGjf3OPvFP9ptZY/wM= -----END RSA PRIVATE KEY-----

It looks right if I check it with:

openssl asn1parse -in output.key -inform PEM

I get:

0:d=0 hl=4 l= 793 cons: SEQUENCE 4:d=1 hl=2 l= 1 prim: INTEGER :00 7:d=1 hl=4 l= 257 prim: INTEGER :A961D0ECAEEC54D59BE1065ED9315D0DE387DF3C18554F1A196921F4A99449A76904BA5685E8348E1031F6FF7EEBB70DFB22711CCD3648E426821937685286FEEDFDB66DEBC462EB9443088AB51363D67AD2868CF4D395F50D19E6C49D3482DF78C719D3532B1E5A890BF2234CF00D3F2867DE2D96E199609E640BBEF52FA540F061EC4E077DDEFC365FEB8396EC33A3876AA53614D8C71A377CA24003E0BF7422F92072F94D6607AE550B3BB6D5222B1F9543638727C459C7D107CFD77CDDBED8D7016B0A7E3886F33E98A4DE654D2AE21871FEC98D52A07093FB0D8BF3086CA8A654D03AB71E91220EE94857A9CE0377CB67D255D120F055D6776FCD815EEB 268:d=1 hl=2 l= 3 prim: INTEGER :010001 273:d=1 hl=4 l= 256 prim: INTEGER :2B39939BFAEDC39E79779CED128726E496F68310EE72C2CB79C59B0D394366E26A89F2D586B9A1C3C93D3EF7A79796B0E230416664B62036DCDEE17982CD60B6E8DC10B48F709FFFD7679DE3EBDEC5612419DA8D59232FC707EF5EB5391AFFF4F078FACDB39132DF4ECEF61D6D126B86FD14389E30BD64AB43F06B10F1B81577092AE4C5BD0E27DA572469C99794083266601D7A5754E82F6CFACB7EBDF276E4E69B155A3C1723FBA5AF76292F848034D44D4257A9CCCD1D825B7D62956C0B3D9C19C39D4DEE944DA99B8F0B1DB82A792DAD7A3BC8208678EDB1915AE7606E97856A65CF11FD0EC37018367B535C2A4A29D44DFBE5CAE6F031DAB8B0ECBB96B9 533:d=1 hl=3 l= 129 prim: INTEGER :C999E70B8B46C407AEEC6F8DFB3C5BF1D3A91EB93CF15B17468347D6C8F9E022308FECBBEDA9B1E09E960B0FF2EC0F4BFCADC5A67DC26E37B930D409962CC32E0F0D74A59F0B6CA7B64643F125446D4D44B210E3F2D5A13194A42A9DCFECA33586DD5BF0E91B6A7F503529F1FB6CBB126B5DDB1EFCCE300526DEBAC89192C7F9 665:d=1 hl=3 l= 129 prim: INTEGER :D7164D0625EAAA036E30DCB0F18A92E01C8DE7B5C3D3413D2C7FC7539E1E2FAB02914E8333B11C869CB6939AC88BAAECD7F1F18D2F6939C7A9A95E0B13ED10D3FAF08C6CFBC56B59CB4A42375FA7C56707B42F81AE206BD94136FF8558208A3E518553DD56F2C7C8F22167C9FDAE30884D3CDE71A37F738FBC53FDA6D658FF03 But if I check with: openssl rsa -in output.key -inform PEM -check

The result gives the following error output: unable to load Private Key 140197225162392:error:0D078079:asn1 encoding routines:ASN1_ITEM_EX_D2I:field missing:tasn_dec.c:487:Field=dmp1, Type=RSA 140197225162392:error:04093004:rsa routines:OLD_RSA_PRIV_DECODE:RSA lib:rsa_ameth.c:119: 140197225162392:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1197: 140197225162392:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:374:Type=X509_ALGOR 140197225162392:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:tasn_dec.c:697:Field=pkeyalg, Type=PKCS8_PRIV_KEY_INFO 140197225162392:error:0907B00D:PEM routines:PEM_READ_BIO_PRIVATEKEY:ASN1 lib:pem_pkey.c:141: