How to: Use the cryptography APIs

Learn how to encrypt and decrypt files

Now that you’ve read about Cryptography as a Dapr building block, let’s walk through using the cryptography APIs with the SDKs.

Note

Dapr cryptography is currently in alpha.

Encrypt

Using the Dapr SDK in your project, with the gRPC APIs, you can encrypt data in a buffer or a string:

  1. // When passing data (a buffer or string), `encrypt` returns a Buffer with the encrypted message
  2. const ciphertext = await client.crypto.encrypt(plaintext, {
  3. // Name of the Dapr component (required)
  4. componentName: "mycryptocomponent",
  5. // Name of the key stored in the component (required)
  6. keyName: "mykey",
  7. // Algorithm used for wrapping the key, which must be supported by the key named above.
  8. // Options include: "RSA", "AES"
  9. keyWrapAlgorithm: "RSA",
  10. });

The APIs can also be used with streams, to encrypt data more efficiently when it comes from a stream. The example below encrypts a file, writing to another file, using streams:

  1. // `encrypt` can be used as a Duplex stream
  2. await pipeline(
  3. fs.createReadStream("plaintext.txt"),
  4. await client.crypto.encrypt({
  5. // Name of the Dapr component (required)
  6. componentName: "mycryptocomponent",
  7. // Name of the key stored in the component (required)
  8. keyName: "mykey",
  9. // Algorithm used for wrapping the key, which must be supported by the key named above.
  10. // Options include: "RSA", "AES"
  11. keyWrapAlgorithm: "RSA",
  12. }),
  13. fs.createWriteStream("ciphertext.out"),
  14. );

Using the Dapr SDK in your project, you can encrypt a stream of data, such as a file.

  1. out, err := sdkClient.Encrypt(context.Background(), rf, dapr.EncryptOptions{
  2. // Name of the Dapr component (required)
  3. ComponentName: "mycryptocomponent",
  4. // Name of the key stored in the component (required)
  5. KeyName: "mykey",
  6. // Algorithm used for wrapping the key, which must be supported by the key named above.
  7. // Options include: "RSA", "AES"
  8. Algorithm: "RSA",
  9. })

The following example puts the Encrypt API in context, with code that reads the file, encrypts it, then stores the result in another file.

  1. // Input file, clear-text
  2. rf, err := os.Open("input")
  3. if err != nil {
  4. panic(err)
  5. }
  6. defer rf.Close()
  7. // Output file, encrypted
  8. wf, err := os.Create("output.enc")
  9. if err != nil {
  10. panic(err)
  11. }
  12. defer wf.Close()
  13. // Encrypt the data using Dapr
  14. out, err := sdkClient.Encrypt(context.Background(), rf, dapr.EncryptOptions{
  15. // These are the 3 required parameters
  16. ComponentName: "mycryptocomponent",
  17. KeyName: "mykey",
  18. Algorithm: "RSA",
  19. })
  20. if err != nil {
  21. panic(err)
  22. }
  23. // Read the stream and copy it to the out file
  24. n, err := io.Copy(wf, out)
  25. if err != nil {
  26. panic(err)
  27. }
  28. fmt.Println("Written", n, "bytes")

The following example uses the Encrypt API to encrypt a string.

  1. // Input string
  2. rf := strings.NewReader("Amor, ch’a nullo amato amar perdona, mi prese del costui piacer sì forte, che, come vedi, ancor non m’abbandona")
  3. // Encrypt the data using Dapr
  4. enc, err := sdkClient.Encrypt(context.Background(), rf, dapr.EncryptOptions{
  5. ComponentName: "mycryptocomponent",
  6. KeyName: "mykey",
  7. Algorithm: "RSA",
  8. })
  9. if err != nil {
  10. panic(err)
  11. }
  12. // Read the encrypted data into a byte slice
  13. enc, err := io.ReadAll(enc)
  14. if err != nil {
  15. panic(err)
  16. }

Decrypt

Using the Dapr SDK, you can decrypt data in a buffer or using streams.

  1. // When passing data as a buffer, `decrypt` returns a Buffer with the decrypted message
  2. const plaintext = await client.crypto.decrypt(ciphertext, {
  3. // Only required option is the component name
  4. componentName: "mycryptocomponent",
  5. });
  6. // `decrypt` can also be used as a Duplex stream
  7. await pipeline(
  8. fs.createReadStream("ciphertext.out"),
  9. await client.crypto.decrypt({
  10. // Only required option is the component name
  11. componentName: "mycryptocomponent",
  12. }),
  13. fs.createWriteStream("plaintext.out"),
  14. );

To decrypt a file, use the Decrypt gRPC API to your project.

In the following example, out is a stream that can be written to file or read in memory, as in the examples above.

  1. out, err := sdkClient.Decrypt(context.Background(), rf, dapr.EncryptOptions{
  2. // Only required option is the component name
  3. ComponentName: "mycryptocomponent",
  4. })

Next steps

Cryptography component specs

Last modified June 19, 2023: Merge pull request #3565 from dapr/aacrawfi/skip-secrets-close (b1763bf)