Skip to content

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

Description

@elenatorroglosa

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:

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions