快速入门:加密

开始使用 Dapr 的 Cryptography 构建块

Alpha

密码学构建块目前处于alpha阶段。

让我们来看看Dapr的cryptography构建块。 在此快速入门中,您将创建一个应用程序,使用 Dapr 加密和解密数据的 API。 您将:

  • 使用RSA密钥对短字符串进行加密和解密,在Go字节切片中读取结果。
  • 使用流加密和解密大文件(使用AES密钥),将加密和解密的数据存储到文件中。

Cryptography - 图1

Note

这个示例使用的是 Dapr SDK,它利用 gRPC 并且在使用加密 API 加密和解密消息时强烈推荐使用。

当前,您可以使用Go SDK来体验密码学 API。

此快速入门包括一个名为 crypto-quickstart 的 JavaScript 应用程序。

先决条件

对于此示例,您将需要:

第1步:设置环境

克隆在Quickstarts存储库中提供的示例

  1. git clone https://github.com/dapr/quickstarts.git

在终端中,从根目录导航到 cryptography 示例。

  1. cd cryptography/javascript/sdk

导航到包含源代码的文件夹中:

  1. cd ./crypto-quickstart

安装依赖项:

  1. npm install

步骤 2:使用 Dapr 运行应用程序

应用程序代码定义了两个必需的键:

  • 私有RSA密钥
  • 一个256位的对称(AES)密钥

使用OpenSSL生成两个密钥,一个RSA密钥和一个AES密钥,并将其写入两个文件中:

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

使用 Dapr 运行 Go 服务应用程序:

  1. dapr run --app-id crypto-quickstart --resources-path ../../../components/ -- npm start

预期输出

  1. == APP == 2023-10-25T14:30:50.435Z INFO [GRPCClient, GRPCClient] Opening connection to 127.0.0.1:58173
  2. == APP == == Encrypting message using buffers
  3. == APP == Encrypted the message, got 856 bytes
  4. == APP == == Decrypting message using buffers
  5. == APP == Decrypted the message, got 24 bytes
  6. == APP == The secret is "passw0rd"
  7. == APP == == Encrypting message using streams
  8. == APP == Encrypting federico-di-dio-photography-Q4g0Q-eVVEg-unsplash.jpg to encrypted.out
  9. == APP == Encrypted the message to encrypted.out
  10. == APP == == Decrypting message using streams
  11. == APP == Decrypting encrypted.out to decrypted.out.jpg
  12. == APP == Decrypted the message to decrypted.out.jpg

发生了什么?

local-storage.yaml

早些时候,您在 crypto-quickstarts 中创建了一个名为 keys 的目录。 在local-storage组件的YAML文件中,path元数据映射到新创建的keys目录。

  1. apiVersion: dapr.io/v1alpha1
  2. kind: Component
  3. metadata:
  4. name: localstorage
  5. spec:
  6. type: crypto.dapr.localstorage
  7. version: v1
  8. metadata:
  9. - name: path
  10. # Path is relative to the folder where the example is located
  11. value: ./keys

index.mjs

应用程序文件 使用您生成的RSA和AES密钥加密和解密消息和文件。 应用程序创建一个新的 Dapr SDK 客户端:

  1. async function start() {
  2. const client = new DaprClient({
  3. daprHost,
  4. daprPort,
  5. communicationProtocol: CommunicationProtocolEnum.GRPC,
  6. });
  7. // Encrypt and decrypt a message from a buffer
  8. await encryptDecryptBuffer(client);
  9. // Encrypt and decrypt a message using streams
  10. await encryptDecryptStream(client);
  11. }
使用 RSA 密钥加密和解密字符串

一旦客户端创建完成,应用程序会对消息进行加密:

  1. async function encryptDecryptBuffer(client) {
  2. // Message to encrypt
  3. const plaintext = `The secret is "passw0rd"`
  4. // First, encrypt the message
  5. console.log("== Encrypting message using buffers");
  6. const encrypted = await client.crypto.encrypt(plaintext, {
  7. componentName: "localstorage",
  8. keyName: "rsa-private-key.pem",
  9. keyWrapAlgorithm: "RSA",
  10. });
  11. console.log("Encrypted the message, got", encrypted.length, "bytes");

然后应用程序解密消息:

  1. // Decrypt the message
  2. console.log("== Decrypting message using buffers");
  3. const decrypted = await client.crypto.decrypt(encrypted, {
  4. componentName: "localstorage",
  5. });
  6. console.log("Decrypted the message, got", decrypted.length, "bytes");
  7. console.log(decrypted.toString("utf8"));
  8. // ...
  9. }
使用AES密钥加密和解密大文件

接下来,应用程序对一个大型图像文件进行加密:

  1. async function encryptDecryptStream(client) {
  2. // First, encrypt the message
  3. console.log("== Encrypting message using streams");
  4. console.log("Encrypting", testFileName, "to encrypted.out");
  5. await pipeline(
  6. createReadStream(testFileName),
  7. await client.crypto.encrypt({
  8. componentName: "localstorage",
  9. keyName: "symmetric-key-256",
  10. keyWrapAlgorithm: "A256KW",
  11. }),
  12. createWriteStream("encrypted.out"),
  13. );
  14. console.log("Encrypted the message to encrypted.out");

接下来,应用程序解密大型图像文件:

  1. // Decrypt the message
  2. console.log("== Decrypting message using streams");
  3. console.log("Decrypting encrypted.out to decrypted.out.jpg");
  4. await pipeline(
  5. createReadStream("encrypted.out"),
  6. await client.crypto.decrypt({
  7. componentName: "localstorage",
  8. }),
  9. createWriteStream("decrypted.out.jpg"),
  10. );
  11. console.log("Decrypted the message to decrypted.out.jpg");
  12. }

此快速入门包括一个名为 crypto-quickstart 的 Go 应用程序。

先决条件

对于此示例,您将需要:

第1步:设置环境

克隆在Quickstarts存储库中提供的示例

  1. git clone https://github.com/dapr/quickstarts.git

在终端中,从根目录导航到 cryptography 示例。

  1. cd cryptography/go/sdk

步骤 2:使用 Dapr 运行应用程序

导航到包含源代码的文件夹中:

  1. cd ./crypto-quickstart

应用程序代码定义了两个必需的键:

  • 私有RSA密钥
  • 一个256位的对称(AES)密钥

使用OpenSSL生成两个密钥,一个RSA密钥和一个AES密钥,并将其写入两个文件中:

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

使用 Dapr 运行 Go 服务应用程序:

  1. dapr run --app-id crypto-quickstart --resources-path ../../../components/ -- go run .

预期输出

  1. == APP == dapr client initializing for: 127.0.0.1:52407
  2. == APP == Encrypted the message, got 856 bytes
  3. == APP == Decrypted the message, got 24 bytes
  4. == APP == The secret is "passw0rd"
  5. == APP == Wrote decrypted data to encrypted.out
  6. == APP == Wrote decrypted data to decrypted.out.jpg

发生了什么?

local-storage.yaml

早些时候,您在 crypto-quickstarts 中创建了一个名为 keys 的目录。 在local-storage组件的YAML文件中,path元数据映射到新创建的keys目录。

  1. apiVersion: dapr.io/v1alpha1
  2. kind: Component
  3. metadata:
  4. name: localstorage
  5. spec:
  6. type: crypto.dapr.localstorage
  7. version: v1
  8. metadata:
  9. - name: path
  10. # Path is relative to the folder where the example is located
  11. value: ./keys

app.go

应用程序文件 使用您生成的RSA和AES密钥加密和解密消息和文件。 应用程序创建一个新的 Dapr SDK 客户端:

  1. func main() {
  2. // Create a new Dapr SDK client
  3. client, err := dapr.NewClient()
  4. //...
  5. // Step 1: encrypt a string using the RSA key, then decrypt it and show the output in the terminal
  6. encryptDecryptString(client)
  7. // Step 2: encrypt a large file and then decrypt it, using the AES key
  8. encryptDecryptFile(client)
  9. }
使用 RSA 密钥加密和解密字符串

一旦客户端创建完成,应用程序会对消息进行加密:

  1. func encryptDecryptString(client dapr.Client) {
  2. // ...
  3. // Encrypt the message
  4. encStream, err := client.Encrypt(context.Background(),
  5. strings.NewReader(message),
  6. dapr.EncryptOptions{
  7. ComponentName: CryptoComponentName,
  8. // Name of the key to use
  9. // Since this is a RSA key, we specify that as key wrapping algorithm
  10. KeyName: RSAKeyName,
  11. KeyWrapAlgorithm: "RSA",
  12. },
  13. )
  14. // ...
  15. // The method returns a readable stream, which we read in full in memory
  16. encBytes, err := io.ReadAll(encStream)
  17. // ...
  18. fmt.Printf("Encrypted the message, got %d bytes\n", len(encBytes))

然后应用程序解密消息:

  1. // Now, decrypt the encrypted data
  2. decStream, err := client.Decrypt(context.Background(),
  3. bytes.NewReader(encBytes),
  4. dapr.DecryptOptions{
  5. // We just need to pass the name of the component
  6. ComponentName: CryptoComponentName,
  7. // Passing the name of the key is optional
  8. KeyName: RSAKeyName,
  9. },
  10. )
  11. // ...
  12. // The method returns a readable stream, which we read in full in memory
  13. decBytes, err := io.ReadAll(decStream)
  14. // ...
  15. // Print the message on the console
  16. fmt.Printf("Decrypted the message, got %d bytes\n", len(decBytes))
  17. fmt.Println(string(decBytes))
  18. }
使用AES密钥加密和解密大文件

接下来,应用程序对一个大型图像文件进行加密:

  1. func encryptDecryptFile(client dapr.Client) {
  2. const fileName = "liuguangxi-66ouBTTs_x0-unsplash.jpg"
  3. // Get a readable stream to the input file
  4. plaintextF, err := os.Open(fileName)
  5. // ...
  6. defer plaintextF.Close()
  7. // Encrypt the file
  8. encStream, err := client.Encrypt(context.Background(),
  9. plaintextF,
  10. dapr.EncryptOptions{
  11. ComponentName: CryptoComponentName,
  12. // Name of the key to use
  13. // Since this is a symmetric key, we specify AES as key wrapping algorithm
  14. KeyName: SymmetricKeyName,
  15. KeyWrapAlgorithm: "AES",
  16. },
  17. )
  18. // ...
  19. // Write the encrypted data to a file "encrypted.out"
  20. encryptedF, err := os.Create("encrypted.out")
  21. // ...
  22. encryptedF.Close()
  23. fmt.Println("Wrote decrypted data to encrypted.out")

接下来,应用程序解密大型图像文件:

  1. // Now, decrypt the encrypted data
  2. // First, open the file "encrypted.out" again, this time for reading
  3. encryptedF, err = os.Open("encrypted.out")
  4. // ...
  5. defer encryptedF.Close()
  6. // Now, decrypt the encrypted data
  7. decStream, err := client.Decrypt(context.Background(),
  8. encryptedF,
  9. dapr.DecryptOptions{
  10. // We just need to pass the name of the component
  11. ComponentName: CryptoComponentName,
  12. // Passing the name of the key is optional
  13. KeyName: SymmetricKeyName,
  14. },
  15. )
  16. // ...
  17. // Write the decrypted data to a file "decrypted.out.jpg"
  18. decryptedF, err := os.Create("decrypted.out.jpg")
  19. // ...
  20. decryptedF.Close()
  21. fmt.Println("Wrote decrypted data to decrypted.out.jpg")
  22. }

观看演示

请观看 Dapr Community Call #83中的密码学API演示视频:

告诉我们您的想法

我们一直在努力改进我们的快速入门示例,并重视您的反馈。 您觉得此快速入门有帮助吗? 您有改进的建议吗?

加入我们的discord频道参与讨论。

下一步

探索 Dapr 教程 >>