Skip to content

Commit

Permalink
add python-sdk in cryptography (#1093)
Browse files Browse the repository at this point in the history
Signed-off-by: KentHsu <[email protected]>
Signed-off-by: Alice Gibbons <[email protected]>
  • Loading branch information
KentHsu authored and alicejgibbons committed Jan 20, 2025
1 parent a273031 commit 46658b1
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 0 deletions.
74 changes: 74 additions & 0 deletions cryptography/python/sdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Dapr cryptography (Dapr SDK)

In this quickstart, you'll create an application that encrypts, and then decrypts, data using the Dapr cryptography APIs (high-level). We will:

- Encrypt and then decrypt a short string, reading the result in-memory
- Encrypt and then decrypt a large file, storing the encrypted and decrypted data to files

Visit the documentation to learn more about the [Cryptography building block](https://v1-11.docs.dapr.io/developing-applications/building-blocks/cryptography/) in Dapr.

> **Note:** This example uses the Dapr SDK. Using the Dapr SDK, which leverages gRPC internally, is **strongly** recommended when using the high-level cryptography APIs (to encrypt and decrypt messages).
This quickstart includes one application:

- Python application `crypto-quickstart`

### Run Python service with Dapr

> In order to run this sample, make sure that OpenSSL is available on your system.
1. Navigate into the folder with the source code:

<!-- STEP
name: Navigate into folder
expected_stdout_lines:
expected_stderr_lines:
-->

```bash
cd ./crypto-quickstart
pip3 install -r requirements.txt
```

<!-- END_STEP -->

2. This sample requires a private RSA key and a 256-bit symmetric (AES) key. We will generate them using OpenSSL:

<!-- STEP
name: Generate keys
working_dir: crypto-quickstart
expected_stdout_lines:
expected_stderr_lines:
-->

```bash
mkdir -p keys
# Generate a private RSA key, 4096-bit keys
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out keys/rsa-private-key.pem
# Generate a 256-bit key for AES
openssl rand -out keys/symmetric-key-256 32
```

<!-- END_STEP -->

3. Run the Python service app with Dapr:

<!-- STEP
name: Run order-processor service
working_dir: crypto-quickstart
expected_stdout_lines:
- '== APP == Encrypted the message, got 856 bytes'
- '== APP == Decrypted the message, got 24 bytes'
- '== APP == The secret is "passw0rd"'
- '== APP == Wrote decrypted data to encrypted.out'
- '== APP == Wrote decrypted data to decrypted.out.jpg'
- "Exited App successfully"
expected_stderr_lines:
output_match_mode: substring
-->

```bash
dapr run --app-id crypto-quickstart --resources-path ../../../components/ -- python3 app.py
```

<!-- END_STEP -->
6 changes: 6 additions & 0 deletions cryptography/python/sdk/crypto-quickstart/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Output files
encrypted.out
decrypted.out.jpg

# Generated keys
keys/
95 changes: 95 additions & 0 deletions cryptography/python/sdk/crypto-quickstart/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
from dapr.clients import DaprClient
from dapr.clients.grpc._crypto import EncryptOptions, DecryptOptions

# Name of the crypto component to use
CRYPTO_COMPONENT_NAME = 'localstorage'
# Name of the RSA private key to use
RSA_KEY_NAME = 'rsa-private-key.pem'
# Name of the symmetric (AES) key to use
SYMMETRIC_KEY_NAME = 'symmetric-key-256'


def main():
print('Running gRPC client synchronous API')

with DaprClient() as dapr:
# Step 1: encrypt a string using the RSA key, then decrypt it and show the output in the terminal
print('Running encrypt/decrypt operation on string')
encrypt_decrypt_string(dapr)

# Step 2: encrypt a large file and then decrypt it, using the AES key
print('Running encrypt/decrypt operation on file')
encrypt_decrypt_file(dapr)


def encrypt_decrypt_string(dapr: DaprClient):
message = 'The secret is "passw0rd"'

# Encrypt the message
resp = dapr.encrypt(
data=message.encode(),
options=EncryptOptions(
component_name=CRYPTO_COMPONENT_NAME,
key_name=RSA_KEY_NAME,
key_wrap_algorithm='RSA',
),
)

# The method returns a readable stream, which we read in full in memory
encrypt_bytes = resp.read()
print(f'Encrypted the message, got {len(encrypt_bytes)} bytes')

# Decrypt the encrypted data
resp = dapr.decrypt(
data=encrypt_bytes,
options=DecryptOptions(
component_name=CRYPTO_COMPONENT_NAME,
key_name=RSA_KEY_NAME,
),
)

# The method returns a readable stream, which we read in full in memory
decrypt_bytes = resp.read()
print(f'Decrypted the message, got {len(decrypt_bytes)} bytes')

print(decrypt_bytes.decode())
assert message == decrypt_bytes.decode()


def encrypt_decrypt_file(dapr: DaprClient):
file_name = 'desert.jpg'

# Encrypt the file
with open(file_name, 'r+b') as target_file:
encrypt_stream = dapr.encrypt(
data=target_file.read(),
options=EncryptOptions(
component_name=CRYPTO_COMPONENT_NAME,
key_name=SYMMETRIC_KEY_NAME,
key_wrap_algorithm='AES',
),
)

# Write the encrypted data to a file "encrypted.out"
with open('encrypted.out', 'w+b') as encrypted_file:
encrypted_file.write(encrypt_stream.read())
print('Wrote encrypted data to encrypted.out')

# Decrypt the encrypted data
with open('encrypted.out', 'r+b') as encrypted_file:
decrypt_stream = dapr.decrypt(
data=encrypted_file.read(),
options=DecryptOptions(
component_name=CRYPTO_COMPONENT_NAME,
key_name=SYMMETRIC_KEY_NAME,
),
)

# Write the decrypted data to a file "decrypted.out.jpg"
with open('decrypted.out.jpg', 'w+b') as decrypted_file:
decrypted_file.write(decrypt_stream.read())
print('Wrote decrypted data to decrypted.out.jpg')


if __name__ == '__main__':
main()
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions cryptography/python/sdk/crypto-quickstart/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dapr>=1.13.0a,<1.14.0
typing-extensions
9 changes: 9 additions & 0 deletions cryptography/python/sdk/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
include ../../../docker.mk
include ../../../validate.mk

# Remove generated files
.PHONY: clean
clean:
-rm -r crypto-quickstart/keys
-rm crypto-quickstart/encrypted.out
-rm crypto-quickstart/decrypted.out.jpg

0 comments on commit 46658b1

Please sign in to comment.