hbldh / pybankid

BankID Relying Party client for Python
https://pybankid.readthedocs.io
MIT License
48 stars 19 forks source link

Support Signature Verification #15

Closed sheepsy90 closed 4 years ago

sheepsy90 commented 6 years ago

Hey,

I read that in issue https://github.com/hbldh/pybankid/issues/5 the decision was made to not include signature verification. I however would like to challenge that again and maybe we can come up with an extension to this library.

I have contacted BankID and got the necessary certificate, however the documentation on their site is very sparse and it makes it very complicated, especially as I am not an expert in all the details about certificates.

My goal:

Having a discussion again if it should be part of this library, otherwise provide a working guide with coding examples to include a step by step guide that at least gives more instructions to users of this library (maybe in a readme)

hbldh commented 6 years ago

I did give this a lot of thought before I decided that I would not do it. You are more than welcome to make the attempt, but I have decided that I will not invest any time in it since it seemed to be a slippery slope and I have more than enough of those as it is... It would also require knowing more cryptography and OpenSSL knowhow than I currently possess.

This is a good SE question to start with. The problem using a Python approach to this can be followed in this cryptography issue and this pyopenssl PR.

I did envision a Windows only solution as a start, using the dotnet package (https://pythonnet.github.io) and calling the .NET X509 certificate chain functions for it. Might be fun to explore, but I am not sure if it is a useful solution though.

sheepsy90 commented 6 years ago

Thanks for the starting points. I need to build something that allows us to verify signatures and gives a guide to do this so I will give it a shot. It must be possible somehow.

Will read through the links you provided. Sadly the same as you my knowledge about this is limited.

sheepsy90 commented 6 years ago

I tried to understand all the parts so far and came up with an a python/OpenSSL implementation. It is not working completely for a reason I don't understand. I was provided the PDF of their signature document. BankID_SignatureProfile_v23.pdf

Let me explain what I did so far.

  1. I decode the base64 signature which results an XML

  2. I take the part of the XML that is the signed data and compute the sha265

  3. This matches the message digest also stated in the XML (I interpret this as - I am using the right data as input to the signature verification)

  4. I extract the users certificate that is included in the XML

  5. I use the user's certificate, the signed raw data, and the provided signature and call

OpenSSL.crypto.verify(user_certificate, signature_bytes, signed_data_raw.encode('utf-8'), 'sha256')

The problem now is that no matter what I do it returns wrong signature. That should not be the case as I input the data that I previously hashed and checked that it matches the digest. I selected the right hashing algorithm. I choose the certificate that it was supposed to be signed with and provide the signature.

sheepsy90 commented 6 years ago

I found my mistake. I gave the wrong data to the signature algorithm. Now need to verify the OCSP response and then I think I have a workable solution.

sheepsy90 commented 6 years ago

@hbldh I have a script that does all the necessary verification in python. It is definitely a little hacky and rather experimental. However it works and I am reasonable confident that it would be a very good resource and starting point for anyone trying to do something with that.

Maybe we can create an experimental part of the package. That would at least put the code into a logical place.

It currently requires the asn1crypto and pyOpenSSL

Maybe someone more sophisticated can reduce this.

hbldh commented 6 years ago

I would gladly take a look at it and maybe include it in e.g. an examples folder. When it has been cleaned up and has tests, maybe it can be included as a separate module in pybankid.

sheepsy90 commented 6 years ago

I will prepare it and also mark everything with TODOs and unsureness markers of things that are definetly not pretty. My main thought here is that it doesn't just lie in my repository after a couple full days of works.

hbldh commented 4 years ago

Merged #16 so I am closing this. Thank you very much, and sorry for taking so long to handle this...