Quickstart: Cryptography
Get started with the Dapr Cryptography building block
Alpha
The cryptography building block is currently in alpha.
Let’s take a look at the Dapr cryptography building block. In this Quickstart, you’ll create an application that encrypts and decrypts data using the Dapr cryptography APIs. You’ll:
- Encrypt and then decrypt a short string (using an RSA key), reading the result in-memory, in a Go byte slice.
- Encrypt and then decrypt a large file (using an AES key), storing the encrypted and decrypted data to files using streams.
Note
This example uses the Dapr SDK, which leverages gRPC and is strongly recommended when using cryptographic APIs to encrypt and decrypt messages.
Currently, you can experience the cryptography API using the Go SDK.
This quickstart includes a Go application called
crypto-quickstart
.
Pre-requisites
For this example, you will need:
- Dapr CLI and initialized environment.
OpenSSL available on your system
Step 1: Set up the environment
Clone the sample provided in the Quickstarts repo
git clone https://github.com/dapr/quickstarts.git
In the terminal, from the root directory, navigate to the cryptography sample.
cd cryptography/go/sdk
Step 2: Run the application with Dapr
Navigate into the folder with the source code:
cd ./crypto-quickstart
The application code defines two required keys:
- Private RSA key
- A 256-bit symmetric (AES) key
Generate two keys, an RSA key and and AES key using OpenSSL and write these to two files:
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
Run the Go service app with Dapr:
dapr run --app-id crypto-quickstart --resources-path ../../../components/ -- go run .
Expected output
== APP == dapr client initializing for: 127.0.0.1:52407
== 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
What happened?
local-storage.yaml
Earlier, you created a directory inside crypto-quickstarts
called keys
. In the local-storage component YAML, the path
metadata maps to the newly created keys
directory.
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: localstorage
spec:
type: crypto.dapr.localstorage
version: v1
metadata:
- name: path
# Path is relative to the folder where the example is located
value: ./keys
app.go
The application file encrypts and decrypts messages and files using the RSA and AES keys that you generated. The application creates a new Dapr SDK client:
func main() {
// Create a new Dapr SDK client
client, err := dapr.NewClient()
//...
// Step 1: encrypt a string using the RSA key, then decrypt it and show the output in the terminal
encryptDecryptString(client)
// Step 2: encrypt a large file and then decrypt it, using the AES key
encryptDecryptFile(client)
}
Encrypting and decrypting a string using the RSA key
Once the client is created, the application encrypts a message:
func encryptDecryptString(client dapr.Client) {
// ...
// Encrypt the message
encStream, err := client.Encrypt(context.Background(),
strings.NewReader(message),
dapr.EncryptOptions{
ComponentName: CryptoComponentName,
// Name of the key to use
// Since this is a RSA key, we specify that as key wrapping algorithm
KeyName: RSAKeyName,
KeyWrapAlgorithm: "RSA",
},
)
// ...
// The method returns a readable stream, which we read in full in memory
encBytes, err := io.ReadAll(encStream)
// ...
fmt.Printf("Encrypted the message, got %d bytes\n", len(encBytes))
The application then decrypts the message:
// Now, decrypt the encrypted data
decStream, err := client.Decrypt(context.Background(),
bytes.NewReader(encBytes),
dapr.DecryptOptions{
// We just need to pass the name of the component
ComponentName: CryptoComponentName,
// Passing the name of the key is optional
KeyName: RSAKeyName,
},
)
// ...
// The method returns a readable stream, which we read in full in memory
decBytes, err := io.ReadAll(decStream)
// ...
// Print the message on the console
fmt.Printf("Decrypted the message, got %d bytes\n", len(decBytes))
fmt.Println(string(decBytes))
}
Encrypt and decrpyt a large file using the AES key
Next, the application encrypts a large image file:
func encryptDecryptFile(client dapr.Client) {
const fileName = "liuguangxi-66ouBTTs_x0-unsplash.jpg"
// Get a readable stream to the input file
plaintextF, err := os.Open(fileName)
// ...
defer plaintextF.Close()
// Encrypt the file
encStream, err := client.Encrypt(context.Background(),
plaintextF,
dapr.EncryptOptions{
ComponentName: CryptoComponentName,
// Name of the key to use
// Since this is a symmetric key, we specify AES as key wrapping algorithm
KeyName: SymmetricKeyName,
KeyWrapAlgorithm: "AES",
},
)
// ...
// Write the encrypted data to a file "encrypted.out"
encryptedF, err := os.Create("encrypted.out")
// ...
encryptedF.Close()
fmt.Println("Wrote decrypted data to encrypted.out")
The application then decrypts the large image file:
// Now, decrypt the encrypted data
// First, open the file "encrypted.out" again, this time for reading
encryptedF, err = os.Open("encrypted.out")
// ...
defer encryptedF.Close()
// Now, decrypt the encrypted data
decStream, err := client.Decrypt(context.Background(),
encryptedF,
dapr.DecryptOptions{
// We just need to pass the name of the component
ComponentName: CryptoComponentName,
// Passing the name of the key is optional
KeyName: SymmetricKeyName,
},
)
// ...
// Write the decrypted data to a file "decrypted.out.jpg"
decryptedF, err := os.Create("decrypted.out.jpg")
// ...
decryptedF.Close()
fmt.Println("Wrote decrypted data to decrypted.out.jpg")
}
Watch the demo
Watch this demo video of the cryptography API from the Dapr Community Call #83:
Tell us what you think!
We’re continuously working to improve our Quickstart examples and value your feedback. Did you find this Quickstart helpful? Do you have suggestions for improvement?
Join the discussion in our discord channel.
Next steps
- Walk through more examples of encrypting and decrypting using the cryptography API
- Learn more about cryptography as a Dapr building block
Last modified October 12, 2023: Update config.toml (#3826) (0ffc2e7)