add python-sdk in cryptography (#1093)

Signed-off-by: KentHsu <chiahaohsu9@gmail.com>
This commit is contained in:
Kent (Chia-Hao), Hsu 2025-01-15 01:24:16 +08:00 committed by GitHub
parent c32f421eae
commit 42a99c20a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 186 additions and 0 deletions

View File

@ -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 -->

View File

@ -0,0 +1,6 @@
# Output files
encrypted.out
decrypted.out.jpg
# Generated keys
keys/

View File

@ -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()

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 MiB

View File

@ -0,0 +1,2 @@
dapr>=1.13.0a,<1.14.0
typing-extensions

View File

@ -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