-
Notifications
You must be signed in to change notification settings - Fork 2
Ecdsa better read me #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
damnkunze
wants to merge
50
commits into
ecdsa-examples
Choose a base branch
from
ecdsa-betterReadMe
base: ecdsa-examples
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
50 commits
Select commit
Hold shift + click to select a range
6671459
Added and refined Doxygen: Documentation-Autogenerate System
damnkunze 74d3727
Small improvements in Readme and examples-Readme
damnkunze 81acee1
Optimized docstrings for Doxygen
damnkunze d449493
Reorganized Documentation files and moved most examples into /tools/
damnkunze e3fd025
Short Quickstart and Step by step examples implemented and documented…
damnkunze acde632
Repo cleanup: files present twice, test-web-of-trust.py doesnt work a…
damnkunze 6bdccea
Update QuickstartExample.py
damnkunze 48c0da3
Update StepByStepExample.py
damnkunze 0752891
Structure change: Documentation .md files should be in the repository…
damnkunze d41778f
help got merge conflicts
damnkunze 56f8ce3
docs rename
damnkunze cbcdac9
README.md is the same as index.md + Quickstart.md
damnkunze cde6a83
Set theme jekyll-theme-minimal
damnkunze 8ed618f
Readme imporved
damnkunze 2fba4e1
Merge branch 'ecdsa-betterReadMe' of https://github.com/ubirch/ubirch…
damnkunze d15955e
Use the same theme as the main page
damnkunze 3dd172b
moved img folder
damnkunze 66dea8b
testing html comparability
damnkunze 4656e8f
Update index.md
damnkunze a9f7128
Added other doc links to README
damnkunze f372217
Added other doc links to gh pages index.md
damnkunze 2c32301
Added other doc links to gh pages index.md 2
damnkunze d86c629
Implement Github Action to push doxygen-func-doc to other repo. Done …
damnkunze f092c92
Completed seperation of function-documentation and Textual Documentat…
damnkunze 3fbacfa
Missing Titles & improved linking
damnkunze 453e4e9
Updated Headlines
damnkunze ad8e2af
Updated Headlines
damnkunze de9aadc
Jekyll now can be run locally and produce the same results as Github …
damnkunze a625f00
config file has to be in root (/docs) for GH Pages to find it
damnkunze 1dce3cf
Extended docstring-documentation in ubirch-library files + Last adapt…
damnkunze b5f785d
Tweaking of Jekyll Configuration and guides
damnkunze f0ad05b
Better README!
damnkunze 1fe44a0
updated gitignore
damnkunze dae35c5
minors
damnkunze 2493026
Untested (demo broken): Step by Step guide made detailed
damnkunze 587403e
Step by Step is working. Now on prod stage.
damnkunze 39faef6
Minors to clean up for PR to ecdsa-examples
damnkunze 30fb769
ignore Gemfile.lock
damnkunze e1175a2
Changes suggested in the review from @UBOK19 -- PR #19
damnkunze eb987c7
Second fix for PR #19
damnkunze b352b8f
Improvement of examples through thorough testing
damnkunze 4121f06
Improved dostrings in Ubirch package. Removed unneccesary tools. Cont…
damnkunze ede1a7b
partially fix tests
UBOK19 b5eb407
check uuid filtering
UBOK19 8debb34
remove old not implemented exception
UBOK19 82282db
Add note to Readme about "Personal access tokens"
damnkunze 4e642f4
Bumped version of ubirch-protocol to 2.2.0
damnkunze d22a9eb
typo
damnkunze c61c384
Set version on ubirch-prtocol packagee to 3.1.0
damnkunze 3ef05c7
added hashing in _sign() and _verify() for ecdsa, now the tests are w…
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| name: Generate Doc | ||
| on: [push] | ||
| jobs: | ||
| deploys: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v3 | ||
| with: | ||
| ref: '' | ||
|
|
||
| - name: Generate doc with Doxygen | ||
| uses: mattnotmitt/doxygen-action@1.9.1 | ||
| with: | ||
| working-directory: 'docs/doxygen' | ||
| doxyfile-path: './Doxyfile' | ||
|
|
||
| - name: Deploy to func-doc repo | ||
| uses: peaceiris/actions-gh-pages@v3 | ||
| with: | ||
| publish_dir: docs/doxygen/html | ||
| external_repository: ubirch/function_documentation | ||
| personal_token: ${{ secrets.PERSONAL_TOKEN }} | ||
| publish_branch: master | ||
| destination_dir: ${{ github.event.repository.name }} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,230 +1,143 @@ | ||
| # ubirch-protocol for python | ||
| [**Documentation and examples**](https://developer.ubirch.com/ubirch-protocol-python/) | ||
|
|
||
| This is an implementation of the [ubirch-protocol](https://github.com/ubirch/ubirch-protocol) | ||
| for [Python 3](https://www.python.org/). Please see [ubirch-protocol](https://github.com/ubirch/ubirch-protocol) | ||
| for details. | ||
| [**Function Documentation**](https://developer.ubirch.com/function_documentation/ubirch-protocol-python/) | ||
|
|
||
| The library consists of three parts which can be used individually: | ||
| --- | ||
|
|
||
| * `ubirch.API` - a python layer covering the ubirch backend REST API | ||
| * `ubirch.Protocol` - the protocol compiler which packages messages and handles signing and verification | ||
| * `ubirch.KeyStore` - a simple key store based on [pyjks](https://pypi.org/project/pyjks/) to store keys and certificates | ||
| <!-- WHEN EDITING THIS FILE: | ||
| The Getting Started and the README have the same content. | ||
| But for Github to render it as the repo description and Github Pages (Jekyll) to be able to find it, there need to be two. | ||
| The links are different in some places, so please don't just copy paste everything while doing changes. | ||
| --> | ||
|
|
||
| > the [ubirch](https://ubirch.com) protocol uses the [Ed25519](https://ed25519.cr.yp.to/) signature scheme by default. | ||
|
|
||
| ## Usage | ||
| <p align="center"> | ||
| <a href="#installation">Installation</a> • | ||
| <a href="#setup">Setup</a> • | ||
| <a href="#a-minimal-application">A minimal application</a> | ||
| </p> | ||
|
|
||
| Install the library: `pip install ubirch-protocol` | ||
|
|
||
| ### Creating keypair and messages | ||
| --- | ||
|
|
||
| ```python | ||
| import ubirch | ||
| from uuid import UUID | ||
| import binascii | ||
| This repository contains a library providing an implementation of the [Ubirch-protocol](https://github.com/ubirch/ubirch-protocol) in **Python 3**. | ||
|
|
||
| # create a keystore for the device keypair | ||
| keystore = ubirch.KeyStore("demo-device.jks", "keystore") | ||
| That, along with the helper classes `KeyStore` and `API`. These can be used to handle cryptografic keys and to communicate with the Ubirch backend. | ||
|
|
||
| # create a UUID that identifies the device and load or create a keypair | ||
| uuid = UUID(hex="575A5601FD744F8EB6AEEF592CDEE12C") | ||
| if not keystore.exists_signing_key(uuid): | ||
| keystore.create_ed25519_keypair(uuid) | ||
| Additionally, you will find the raw documentation files rendered to the [documentation pages](https://developer.ubirch.com/ubirch-protocol-python/). | ||
|
|
||
| # implement the _sign method of the ubirch.Protocol to use the just created keys to sign the message | ||
| class ProtocolImpl(ubirch.Protocol): | ||
| def _sign(self, uuid: UUID, message: bytes) -> bytes: | ||
| return keystore.find_signing_key(uuid).sign(message) | ||
| ## Installation | ||
| Optionally create environment to install to: | ||
|
|
||
| # create an instance of the ubirch protocol | ||
| proto = ProtocolImpl() | ||
| `$ python -m venv venv` | ||
|
|
||
| # create ubirch protocol messages | ||
| print(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 API | ||
| `$ . venv/bin/activate` | ||
|
|
||
| Please see [test-protocol.py](examples/test-protocol.py) for 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. | ||
| Install the requirements and Ubirch library using pip: | ||
|
|
||
| You will need a password for the ubirch backend. Go to https://console.demo.ubirch.com to register your UUID | ||
| under `Things`. Then click on your device and copy the password from the `apiConfig`-field. | ||
| `$ pip install -r requirements.txt` | ||
|
|
||
| ```python | ||
| import ubirch | ||
| from uuid import UUID | ||
| import binascii | ||
| from datetime import datetime | ||
|
|
||
| # create a keystore for the device key pair | ||
| keystore = ubirch.KeyStore("demo-device.jks", "keystore") | ||
|
|
||
| # create a UUID that identifies the device and load or create a key pair | ||
| uuid = UUID(hex="575A5601FD744F8EB6AEEF592CDEE12C") | ||
| if not keystore.exists_signing_key(uuid): | ||
| keystore.create_ed25519_keypair(uuid) | ||
| `$ pip install ubirch-protocol` | ||
damnkunze marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| > The required version of the `ubirch-protocol` package to run the provided scripts is `3.1.0`. | ||
| > Currently this version can only be installed through a [local install](docs/NotPip.md). | ||
|
|
||
| # implement the _sign method of the ubirch.Protocol | ||
| class ProtocolImpl(ubirch.Protocol): | ||
| def _sign(self, _uuid: UUID, message: bytes) -> bytes: | ||
| return keystore.find_signing_key(uuid).sign(message) | ||
| If you want to install from another source than pip, follow along [here](docs/NotPip.md). | ||
|
|
||
| ## Setup | ||
| Before anything, you will need to do/get a couple of things: | ||
| - Open up the [uBirch Console](https://console.demo.ubirch.com) (`'demo'` stage) | ||
| - For guidance, check out the [uBirch console documentation](https://developer.ubirch.com/console.html) | ||
| - First register to get an account | ||
| - Then Create a "Thing": | ||
| - Using a UUID generated with a [UUID-Generator](https://www.uuidgenerator.net/) | ||
| - You will be using the shown UUID (ID) and the generated Auth-Token (password) from now on | ||
| - Come up or [generate](https://www.random.org/passwords/) a password for the KeyStore, which is where public and private Keys will be stored locally | ||
|
|
||
| # create an instance of the ubirch protocol | ||
| proto = ProtocolImpl() | ||
| > Open up the [Getting started](https://developer.ubirch.com/ubirch-protocol-python/GettingStarted.html) on the [Documentation and Examples](https://developer.ubirch.com/ubirch-protocol-python/) pages or continue below. | ||
|
|
||
| # create an instance of the ubirch API and set the password | ||
| api = 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 1 | ||
| msg = proto.message_chained(uuid, 0x53, {'ts': int(datetime.utcnow().timestamp()), 'v': 99}) | ||
| print(binascii.hexlify(msg)) | ||
| # send message to ubirch backend | ||
| r = 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 backend | ||
| r = api.send(uuid, msg) | ||
| print("{}: {}".format(r.status_code, r.content)) | ||
| ``` | ||
|
|
||
| ### Verification of received message | ||
| ### Now you should have the following at hand: | ||
|
|
||
| Our [Ubirch API](http://developer.ubirch.com/function_documentation/ubirch-protocol-python/) | ||
| authentication with an uuid and a password: | ||
| ```python | ||
| import ubirch | ||
| from ed25519 import VerifyingKey, BadSignatureError | ||
| from uuid import UUID | ||
|
|
||
| remote_uuid = UUID(hex="9d3c78ff22f34441a5d185c636d486ff") | ||
| remote_vk = VerifyingKey("a2403b92bc9add365b3cd12ff120d020647f84ea6983f98bc4c87e0f4be8cd66", encoding='hex') | ||
|
|
||
| # create a keystore and insert the verifying key | ||
| keystore = ubirch.KeyStore("demo-device.jks", "keystore") | ||
| keystore.insert_ed25519_verifying_key(remote_uuid, remote_vk) | ||
|
|
||
| # implement the _verify method of the ubirch.Protocol | ||
| class ProtocolImpl(ubirch.Protocol): | ||
| def _verify(self, uuid: UUID, message: bytes, signature: bytes) -> dict: | ||
| return keystore.find_verifying_key(uuid).verify(signature, message) | ||
|
|
||
| # create an instance of the ubirch protocol | ||
| proto = 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!") | ||
| except BadSignatureError as e: | ||
| print("ERROR: verification failed!") | ||
| uuid = UUID(hex = "f5ded8a3-d462-41c4-a8dc-af3fd072a217") | ||
| auth = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | ||
| ``` | ||
|
|
||
| ### Existing keys | ||
|
|
||
| In case you create a key pair from our demo website, use the following code to insert it into the key store: | ||
|
|
||
| And credentials for a [KeyStore](http://developer.ubirch.com/function_documentation/ubirch-protocol-python/) | ||
| to store your public and private key: | ||
| ```python | ||
| import ubirch | ||
| import ed25519 | ||
| import uuid | ||
|
|
||
| hwDeviceId = 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 example | ||
|
|
||
| ```bash | ||
| python3 -m venv venv3 | ||
| . venv3/bin/activate | ||
| pip install -r requirements.txt | ||
| pip install ubirch-protocol | ||
| PYTHONPATH=. python3 examples/test-protocol.py | ||
| keystore_name = "devices.jks" | ||
| keystore_password = "XXXXXXXXXXX" | ||
| ``` | ||
|
|
||
| At 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 file `demo-device.ini` which is loaded upon running the script again. If | ||
| you need to change anything edit that file. | ||
|
|
||
| The script goes through a number of steps: | ||
| ## A minimal application | ||
| The smallest uBirch application looks something like this. | ||
|
|
||
| 1. checks the existence of the device and deletes the device if it exists | ||
| 2. registers the device with the backend | ||
| 3. generates a new identity for that device and stores it in the key store | ||
| 4. registers the new identity with the backend | ||
| 5. sends two consecutive chained messages to the backend | ||
| *The code can be found in [`GettingStarted.py`](examples/GettingStarted.py) as well.* | ||
|
|
||
| ### Example: Web-of-Trust | ||
| *Run it from your command prompt using `$ python examples/GettingStarted.py` or copy-paste the codeblocks.* | ||
|
|
||
| #### Before First Execution | ||
| Let's say we have got some environment-sensor data like: | ||
|
|
||
| ```bash | ||
| python3 -m venv venv3 | ||
| pip install -r requirements.txt | ||
| ```python | ||
| import time | ||
|
|
||
| data = { | ||
| "timestamp": int(time.time()), | ||
| "temperature": 11.2, | ||
| "humidity": 35.8, | ||
| "status": "OK" | ||
| } | ||
| ``` | ||
|
|
||
| #### Running The Example | ||
|
|
||
| ```bash | ||
| . venv3/bin/activate | ||
| PYTHONPATH=. python3 examples/test-web-of-trust.py | ||
| ``` | ||
| To send a hash of the data to the Ubirch backend run these few lines inside of `examples/`: | ||
| ```python | ||
| import ubirch | ||
| from UbirchWrapper import UbirchWrapper | ||
|
|
||
| During first launch the script generates key pairs for two users. Each user has one device and key pairs are created for | ||
| these, too. All key pairs are stored in `test-web-of-trust.jks` while the association of users, their device and the | ||
| respective key pair is stored in `demo-web-of-trust.ini`. In consecutive runs no new key pairs are generated and instead | ||
| the ones referenced in `demo-web-of-trust.ini` are used. | ||
| # (1) Initialize an UbirchWrapper instance and pass the credentials for a `KeyStore` | ||
| client = UbirchWrapper(uuid, auth, keystore_name, keystore_password) | ||
|
|
||
| The script always uploads all public keys, followed by creating and uploading a web-of-trust and searching all public | ||
| keys trusted by `deviceA`. This search is repeated with different parameters. The results are then printed onto the | ||
| terminal. | ||
| # (2) Check if the public key is registered at the Ubirch key service and register it if necessary | ||
| client.checkRegisterPubkey() | ||
|
|
||
| The web-of-trust created looks as follows (trust knows a direction; always bidirectional in this example): | ||
| # (3) Create a chained Ubirch protocol packet (UPP) that contains a hash of the data | ||
| currentUPP = client.createUPP(data) | ||
|
|
||
| ``` | ||
| deviceA <--trustLevel=100--> user1 <--trustLevel=50--> user2 <--trustLevel=100--> deviceB | ||
| ``` | ||
| # (4) Send the UPP to the Ubirch backend using the API and handle the response | ||
| response = client.api.send(uuid, currentUPP) | ||
| client.handleMessageResponse(response) | ||
|
|
||
| The first search for all trusted keys is for a minimum trust of 50 and a depth of 3 resulting in the the following keys | ||
| being found: | ||
| # (5) Verify that the response came from the backend | ||
| client.verifyResponseSender(response) | ||
|
|
||
| * user1 | ||
| * user2 | ||
| * deviceB | ||
| # (6) Unpack the received UPP to get its previous signature | ||
| previousSignatureInUPP = client.extractPreviousSignature(response) | ||
|
|
||
| The second search increases the minimum trust to 60 resulting in: | ||
| # (7) Make sure it is the same as the UPP signature sent | ||
| client.assertSignatureCorrect(previousSignatureInUPP) | ||
|
|
||
| * user1 | ||
| # (9) Persist signature: Save last signatures to a `.sig` file | ||
| client.protocol.persist(uuid) | ||
|
|
||
| And the third search is with a minimum trust of 50 again while the depth is now 2 resulting in: | ||
| print("Successfully sent the UPP and verified the response!") | ||
| ``` | ||
|
|
||
| * user1 | ||
| * user2 | ||
| *This example uses the example [UbirchWrapper](examples/UbirchWrapper.py) that helps to implement general repetitive tasks.* | ||
|
|
||
| > **Next:** Take a look at the Step-by-step-example on the [Documentation Pages](https://developer.ubirch.com/ubirch-protocol-python/) | ||
damnkunze marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ### Testing | ||
|
|
||
| Unit tests are added to test the functionality of all objects provided in this library. | ||
| ## Testing | ||
| Unit tests are added to test the functionality of objects provided in this library. | ||
|
|
||
| ```bash | ||
| pip install -r requirements.test.txt | ||
| python3 -m pytest tests | ||
| ``` | ||
| # License | ||
|
|
||
| python -m pytest tests | ||
| ``` | ||
|
|
||
| ## Ubirch Internal Documentation | ||
| About the repository automation refer [here](https://ubirch.atlassian.net/wiki/spaces/UBD/pages/2342092819/Template+repository+for+better+documentation). | ||
| - If the deployment fails make sure the Personal access token is up-to-date | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.