Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dreipol/pyattest
https://github.com/dreipol/pyattest
Last synced: 7 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/dreipol/pyattest
- Owner: dreipol
- License: mit
- Created: 2021-01-22T15:10:39.000Z (almost 4 years ago)
- Default Branch: master
- Last Pushed: 2024-08-15T15:19:38.000Z (3 months ago)
- Last Synced: 2024-09-15T18:15:28.904Z (2 months ago)
- Language: Python
- Size: 172 KB
- Stars: 6
- Watchers: 10
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# pyattest
[![Maintainability](https://api.codeclimate.com/v1/badges/bab7989f664ba4a47501/maintainability)](https://codeclimate.com/repos/603674bad5ad4c0176007ce0/maintainability)
pyattest provides a common interface that helps you verify attestations from either [Google](https://developer.android.com/google/play/integrity) or [Apple](https://developer.apple.com/documentation/devicecheck/validating_apps_that_connect_to_your_server). The package works standalone but if you use django and need a full implementation with key generation and storage then [django-dreiattest](https://github.com/dreipol/django-dreiattest) could be of interest for you.
## Installation
pyattest is available on PyPI and can be installed via `$ python -m pip install pyattest`
## Usage
In it's most basic form you can create either a `GoogleConfig`, `GooglePlayIntegrityApiConfig` or `AppleConfig` instance, create an `Attestation` and verify it.
### Google Play Integrity API
The following parameters are important:
- `decryption_key`: A Base64 encoded AES key secret as described [here](https://developer.android.com/google/play/integrity/verdict#decrypt-verify)
- `verification_key`: A Base64 encoded public key as described [here](https://developer.android.com/google/play/integrity/verdict#decrypt-verify)
- `apk_package_name`: Name of your apk
- `allow_non_play_distribution`: Set to true if you want to verify apps distributed via other means than Google Play (you need to set `verify_code_signature_hex`) *Note: should not be used for dev builds set `production` to `False` in that case instead.*
- `verify_code_signature_hex`: The sha256 hash of the signing identity you use for distributing your app. This can be obtained using `./gradlew signingReport` in your Android project.
- `required_device_verdict`: If you want to require stronger integrity guarantees pass [the corresponding key](https://developer.android.com/google/play/integrity/setup#optional_device_information) here.
- `attest`: The jwt object string representing the attestation, which is a jws nested in a jwe object
- `nonce`: The nonce used to create the attestation```python
config = GooglePlayIntegrityApiConfig(
decryption_key=[decryption_key],
verification_key=[decryption_key],
apk_package_name='ch.dreipol.demo',
production=True,
allow_non_play_distribution=True,
verify_code_signature_hex=["00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"],
required_device_verdict="MEETS_STRONG_INTEGRITY"
)
attestation = Attestation(attest, nonce, config)try:
attestation.verify()
except PyAttestException as exception:
# Do your thing
pass
```### Google (Legacy: SafetyNet)
The following parameters are important:
- `key_id`: A Base64 encoded SHA-256 hash of your apps certificate
- `apk_package_name`: Name of your apk
- `production`: Ignores basic integrity and cts profile check if `False`
- `attest`: The jws object string representing the attestation
- `nonce`: The nonce used to create the attestation```python
config = GoogleConfig(key_ids=[key_id], apk_package_name='ch.dreipol.demo', production=True)
attestation = Attestation(attest, nonce, config)try:
attestation.verify()
except PyAttestException as exception:
# Do your thing
pass
```### Apple
The following parameters are important:
- `key_id`: SHA-256 hash of the public key form the cert you got back from the attestation
- `app_id`: Your app’s App ID, which is the concatenation of your 10-digit team identifier, a period, and your app’s CFBundleIdentifier value
- `production`: Checks for the appropriate `aaguid`
- `attest`: The apple attestation as binary
- `nonce`: The nonce used to create the attestation```python
config = AppleConfig(key_id=key_id, app_id='1234ABCDEF.ch.dreipol.demo', production=True)
attestation = Attestation(attest, nonce, config)try:
attestation.verify()
except PyAttestException as exception:
# Do your thing
pass
```### Assertion
Once you verified and obtained a public key, you can use it to `assert` further requests. For a full implementation on how to get to the public key check out [django-dreiattest](https://github.com/dreipol/django-dreiattest/blob/master/dreiattest/key.py). To check if an `assertion` is valid we check if it was signed with given `pem_key`.
- `assertion`: Raw bytes of the assertion you want to test
- `expected_hash`: The hash we want to compare the signature against
- `pem_key`: The public key to verify the signature
- `config`: A `AppleConfig` or `GoogleConfig` instance```
assertion = Assertion(assertion, expected_hash, pem_key, config)
assertion.verify()
```