Package: ubirch-protocol
ubirch-protocol for pythonThis is an implementation of theubirch-protocolforPython 3. Please seeubirch-protocolfor details.The library consists of three parts which can be used individually:ubirch.API- a python layer covering the ubirch backend REST APIubirch.Protocol- the protocol compiler which packages messages and handles signing and verificationubirch.KeyStore- a simple key store based onpyjksto store keys and certificatestheubirchprotocol uses theEd25519signature scheme by default.UsageInstall the library:pip install ubirch-protocolCreating keypair and messagesimportubirchfromuuidimportUUIDimportbinascii# create a keystore for the device keypairkeystore=ubirch.KeyStore("demo-device.jks","keystore")# create a UUID that identifies the device and load or create a keypairuuid=UUID(hex="575A5601FD744F8EB6AEEF592CDEE12C")ifnotkeystore.exists_signing_key(uuid):keystore.create_ed25519_keypair(uuid)# implement the _sign method of the ubirch.Protocol to use the just created keys to sign the messageclassProtocolImpl(ubirch.Protocol):def_sign(self,uuid:UUID,message:bytes)->bytes:returnkeystore.find_signing_key(uuid).sign(message)# create an instance of the ubirch protocolproto=ProtocolImpl()# create ubirch protocol messagesprint(binascii.hexlify(proto.message_chained(uuid,0x00,[1,2,3])))print(binascii.hexlify(proto.message_chained(uuid,0x00,[4,5,6])))Sending messages using the ubirch APIPlease seetest-protocol.pyfor a comprehensive example, how to create a device and
send data. Below is a snipped that will send two chained messages, using a generic key/value payload.You will need a password for the ubirch backend. Go tohttps://console.demo.ubirch.comto register your UUID
underThings. Then click on your device and copy the password from theapiConfig-field.importubirchfromuuidimportUUIDimportbinasciifromdatetimeimportdatetime# create a keystore for the device key pairkeystore=ubirch.KeyStore("demo-device.jks","keystore")# create a UUID that identifies the device and load or create a key pairuuid=UUID(hex="575A5601FD744F8EB6AEEF592CDEE12C")ifnotkeystore.exists_signing_key(uuid):keystore.create_ed25519_keypair(uuid)# implement the _sign method of the ubirch.ProtocolclassProtocolImpl(ubirch.Protocol):def_sign(self,_uuid:UUID,message:bytes)->bytes:returnkeystore.find_signing_key(uuid).sign(message)# create an instance of the ubirch protocolproto=ProtocolImpl()# create an instance of the ubirch API and set the passwordapi=ubirch.API()api.set_authentication(uuid,"<< password for the ubirch backend >>")# register your UUID at https://console.demo.ubirch.com and retrieve your password# message 1msg=proto.message_chained(uuid,0x53,{'ts':int(datetime.utcnow().timestamp()),'v':99})print(binascii.hexlify(msg))# send message to ubirch backendr=api.send(uuid,msg)print("{}:{}".format(r.status_code,r.content))# message 2 (chained to message 1)msg=proto.message_chained(uuid,0x53,{"ts":int(datetime.utcnow().timestamp()),"v":100})print(binascii.hexlify(msg))# send message to ubirch backendr=api.send(uuid,msg)print("{}:{}".format(r.status_code,r.content))Verification of received messageimportubirchfromed25519importVerifyingKey,BadSignatureErrorfromuuidimportUUIDremote_uuid=UUID(hex="9d3c78ff22f34441a5d185c636d486ff")remote_vk=VerifyingKey("a2403b92bc9add365b3cd12ff120d020647f84ea6983f98bc4c87e0f4be8cd66",encoding='hex')# create a keystore and insert the verifying keykeystore=ubirch.KeyStore("demo-device.jks","keystore")keystore.insert_ed25519_verifying_key(remote_uuid,remote_vk)# implement the _verify method of the ubirch.ProtocolclassProtocolImpl(ubirch.Protocol):def_verify(self,uuid:UUID,message:bytes,signature:bytes)->dict:returnkeystore.find_verifying_key(uuid).verify(signature,message)# create an instance of the ubirch protocolproto=ProtocolImpl()message=bytes.fromhex("9623c4109d3c78ff22f34441a5d185c636d486ffc440a5b371acdfc8495790ee86802399585da50401b0d3c87f60946719338eb0283d36c0bac9b8a6a75a5385342e62932335da988b97c0ec211556db082e9f8478070081a76d657373616765bf796f7572207265717565737420686173206265656e207375626d6974746564c440c8529623a4c2335f7a8ae1eeea655768d2e9a0df141f481ced557c9dac7216e8f64ca9f6970fc6c1096ed49bcc6f7fa77d8f85d05bff5e1301588597edc9770e")# verify the message (throws an exception if the message could not be verified)try:print(proto.message_verify(message))print("verification successful!")exceptBadSignatureErrorase:print("ERROR: verification failed!")Existing keysIn case you create a key pair from our demo website, use the following code to insert it into the key store:importubirchimported25519importuuidhwDeviceId=uuid.uuid4()keystore=ubirch.KeyStore("demo-device.jks","keystore")key_encoded=input("paste the encoded private key here:")sk=ed25519.SigningKey(key_encoded,encoding='hex')vk=sk.get_verifying_key()keystore.insert_ed25519_keypair(hwDeviceId,vk,sk)Running the examplepython3-mvenvvenv3
.venv3/bin/activate
pipinstall-rrequirements.txt
pipinstallubirch-protocolPYTHONPATH=.python3examples/test-protocol.pyAt the first launch the script generates a random UUID for your device and you will be asked
about the authentication token and the device group. You can safely ignore the device group, just press Enter.
The script creates a filedemo-device.iniwhich is loaded upon running the script again. If
you need to change anything edit that file.The script goes through a number of steps:checks the existence of the device and deletes the device if it existsregisters the device with the backendgenerates a new identity for that device and stores it in the key storeregisters the new identity with the backendsends two consecutive chained messages to the backendTestingUnit tests are added to test the functionality of all objects provided in this library.pipinstall-rrequirements.test.txt
python3-mpytesttestsLicenseThe protocol and its implementation are publicized under theApache License 2.0.