Package: pybankid
PyBankID is a client for providing BankID services as a Relying Party, i.e.
providing authentication and signing functionality to end users. This package
provides a simplifying interface for initiating authentication
and signing orders and then collecting the results from the BankID servers.If you intend to use PyBankID in your project, you are advised to read
theBankID Relying Party Guidelinesbefore
doing anything else. There, one can find information
about how the BankID methods are defined and how to use them.InstallationPyBankID can be installed though pip:pipinstallpybankidUsageBankIDJSONClientis the client to be used to
communicate with the BankID service. It uses the JSON 5.1 API released in April 2020.JSON client>>>frombankidimportBankIDJSONClient>>>client=BankIDJSONClient(certificates=('path/to/certificate.pem','path/to/key.pem'))Connection to production server is the default in the client. If test
server is desired, send in thetest_server=Truekeyword in the init
of the client.When using the JSON client, authentication and signing calls requires
the end user’s ip address to be included in all calls. An authentication order
is initiated as such:>>>client.authenticate(end_user_ip='194.168.2.25',personal_number="YYYYMMDDXXXX"){'orderRef':'ee3421ea-2096-4000-8130-82648efe0927','autoStartToken':'e8df5c3c-c67b-4a01-bfe5-fefeab760beb','qrStartToken':'01f94e28-857f-4d8a-bf8e-6c5a24466658','qrStartSecret':'b4214886-3b5b-46ab-bc08-6862fddc0e06'}and a sign order is initiated in a similar fashion:>>>client.sign(end_user_ip='194.168.2.25',user_visible_data="The information to sign.",personal_number="YYYYMMDDXXXX"){'orderRef':'ee3421ea-2096-4000-8130-82648efe0927','autoStartToken':'e8df5c3c-c67b-4a01-bfe5-fefeab760beb','qrStartToken':'01f94e28-857f-4d8a-bf8e-6c5a24466658','qrStartSecret':'b4214886-3b5b-46ab-bc08-6862fddc0e06'}Since theBankIDJSONClientis using the BankIDv5JSON API, thepersonal_numbercan now be omitted when callingauthenticateandsign. See BankID Relying Party Guidelines
for more information about this.The status of an order can then be studied by polling
with thecollectmethod using the receivedorderRef:>>>client.collect(order_ref="a9b791c3-459f-492b-bf61-23027876140b"){'hintCode':'outstandingTransaction','orderRef':'a9b791c3-459f-492b-bf61-23027876140b','status':'pending'}>>>client.collect(order_ref="a9b791c3-459f-492b-bf61-23027876140b"){'hintCode':'userSign','orderRef':'a9b791c3-459f-492b-bf61-23027876140b','status':'pending'}>>>client.collect(order_ref="a9b791c3-459f-492b-bf61-23027876140b"){'completionData':{'cert':{'notAfter':'1581289199000','notBefore':'1518130800000'},'device':{'ipAddress':'0.0.0.0'},'ocspResponse':'MIIHegoBAKCCB[...]','signature':'PD94bWwgdmVyc2lv[...]','user':{'givenName':'Namn','name':'Namn Namnsson','personalNumber':'YYYYMMDDXXXX','surname':'Namnsson'}},'orderRef':'a9b791c3-459f-492b-bf61-23027876140b','status':'complete'}Please note that thecollectmethod should be used sparingly: in the
BankID Relying Party Guidelines
it states that“collect should be called every two seconds and must not be
called more frequent than once per second”.PyBankID and QR codePyBankID cannot generate QR codes for you, but there is an example application in theexamples folder of the repowhere a
Flask application calledqrdemoshows one way to do authentication with animated QR codes.The content for the QR code is generated by this method:importhashlibimporthmacfrommathimportfloorimporttimedefgenerate_qr_code_content(qr_start_token:str,start_t:float,qr_start_secret:str):"""Given QR start token, time.time() when initiated authentication call was made and the
QR start secret, calculate the current QR code content to display.
"""elapsed_seconds_since_call=int(floor(time.time()-start_t))qr_auth_code=hmac.new(qr_start_secret.encode(),msg=str(elapsed_seconds_since_call).encode(),digestmod=hashlib.sha256,).hexdigest()returnf"bankid.{qr_start_token}.{elapsed_seconds_since_call}.{qr_auth_code}"CertificatesProduction certificatesIf you want to use BankID in a production environment, then you will have to
purchase this service from one of theselling banks.
They will then provide you with a certificate that can be used to authenticate
your company/application with the BankID servers.This certificate has to be processed somewhat to be able to use with PyBankID,
and how to do this depends on what the selling bank provides you with.Test certificateThe certificate to use when developing against the BankID test servers can
be obtained through PyBankID:>>>importos>>>importbankid>>>dir_to_save_cert_and_key_in=os.path.expanduser('~')>>>cert_and_key=bankid.create_bankid_test_server_cert_and_key(dir_to_save_cert_and_key_in)>>>print(cert_and_key)['/home/hbldh/certificate.pem','/home/hbldh/key.pem']>>>client=bankid.BankIDJSONClient(certificates=cert_and_key,test_server=True)TestingThe PyBankID solution can be tested withpytest:py.test