Office365-REST-Python-Client icon indicating copy to clipboard operation
Office365-REST-Python-Client copied to clipboard

Could not deserialize key data

Open tomwagstaff-opml opened this issue 2 years ago • 2 comments

I am trying to follow the certificate-based authorisation flow (if I understand correctly, this is the only one Microsoft will allow at this point).

I've created the .pem file with openssl, lodged it with the Azure AD app and then followed the instructions here: https://github.com/vgrem/Office365-REST-Python-Client/blob/master/examples/sharepoint/connect_with_client_certificate.py

But on executing the query, I get this error:

ValueError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [_OpenSSLErrorWithText(code=151584876, lib=9, reason=108, reason_text=b'error:0909006C:PEM routines:get_name:no start line')])

I can't find an issue about this, but another user seems to have mentioned it on a closed issue about another problem:

@denicomp Could you tell me how can you generate the PowershellPnP.pem file?

I tried to use the .cer file by: openssl x509 -in cert.cer -out cert.pem

The cer comes from .\Create-SelfSignedCertificate.ps1 in https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread

Then I got error "Could not deserialize key data. The data may be in an incorrect format or it may be encrypted with an unsupported algorithm".

Could you tell me if there is any difference between yours and mine? Thank you very much!

Originally posted by @JusticeGitHub in https://github.com/vgrem/Office365-REST-Python-Client/issues/541#issuecomment-1411322007

tomwagstaff-opml avatar Jun 29 '23 10:06 tomwagstaff-opml

I had the same error following the same steps.

Not sure if you were able to solve it yet, but here is what worked for me:

Either pass cert_path or the private_key (as string) - but not both (see office365 > runtime > auth > authentication_context.py). If cert_path is set this file will be read and set as private_key.

Starting with the pfx from the same powershell script I exported the certificate and the private key (in #PKCS8) in the same file. I guess #PKCS12 works too for the key, but I needed to convert for Azure key vault anyway: openssl pkcs12 -in key.pfx -out temp.pem -nodes openssl x509 -in temp.pem >> cert_and_key.pem openssl pkcs8 -topk8 -nocrypt -in temp.pem >> cert_and_key.pem

cert_and_key.pem can be used as path for cert_path or read and passed as private_key:

cert_credentials = {'tenant': TENANT_ID,
 'client_id': CLIENT_ID,
 'thumbprint': CERT_THUMBPRINT,
'private_key': PRIVATE_KEY,
'scopes' : ["https://<yoursite>.sharepoint.com/.default"]
}
ctx = ClientContext(test_site_url).with_client_certificate(**cert_credentials)
current_web = ctx.web.get().execute_query()
print(f"{current_web.url}")

pclasen-eb avatar Aug 07 '23 21:08 pclasen-eb

Thanks so much @pclasen-eb, I've managed to get a response thanks to you!

The crucial change seemed to be the addition of our SharePoint URL to the scopes argument (I had stumbled upon this somewhere but was just pointing it to the Microsoft Graph API).

I also thought it was really weird that I was sending the private key to the cert_path argument, but that does seem to be working as-is now.

If any package authors are able to clarify the intended usage of this code block that would be really useful, but as long as it works I'm happy!

tomwagstaff-opml avatar Aug 08 '23 10:08 tomwagstaff-opml