• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用SCRYPT进行密钥派生(C/C++)
2
3<!--Kit: Crypto Architecture Kit-->
4<!--Subsystem: Security-->
5<!--Owner: @zxz--3-->
6<!--Designer: @lanming-->
7<!--Tester: @PAFT-->
8<!--Adviser: @zengyawen-->
9
10对应的算法规格请查看[密钥派生算法规格:SCRYPT](crypto-key-derivation-overview.md#scrypt算法)。
11
12## 开发步骤
13
141. 调用[OH_CryptoKdfParams_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-kdf-h.md#oh_cryptokdfparams_create),指定字符串参数'SCRYPT',创建密钥派生参数对象。
15
162. 调用[OH_CryptoKdfParams_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-kdf-h.md#oh_cryptokdfparams_setparam),设置Scrypt所需的参数。
17
18密钥派生失败原因:下列参数未设置。
19   - CRYPTO_KDF_KEY_DATABLOB:用于生成派生密钥的原始密码。
20   - CRYPTO_KDF_SALT_DATABLOB:盐值。
21   - CRYPTO_KDF_SCRYPT_N_UINT64:CPU/内存开销参数,必须是2的幂次方。
22   - CRYPTO_KDF_SCRYPT_R_UINT64:块大小参数,影响并行度。
23   - CRYPTO_KDF_SCRYPT_P_UINT64:并行化参数。
24   - CRYPTO_KDF_SCRYPT_MAX_MEM_UINT64:最大内存限制(字节)。
25
263. 调用[OH_CryptoKdf_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-kdf-h.md#oh_cryptokdf_create),指定字符串参数'SCRYPT',创建密钥派生函数对象。
27
284. 调用[OH_CryptoKdf_Derive](../../reference/apis-crypto-architecture-kit/capi-crypto-kdf-h.md#oh_cryptokdf_derive),指定目标密钥的字节长度,进行密钥派生。
29
30```C++
31#include "CryptoArchitectureKit/crypto_architecture_kit.h"
32#include "CryptoArchitectureKit/crypto_kdf.h"
33#include <stdio.h>
34#include <cstring>
35
36static OH_Crypto_ErrCode doTestScrypt()
37{
38    // 创建Scrypt参数对象。
39    OH_CryptoKdfParams *params = nullptr;
40    OH_Crypto_ErrCode ret = OH_CryptoKdfParams_Create("SCRYPT", &params);
41    if (ret != CRYPTO_SUCCESS) {
42        return ret;
43    }
44
45    // 设置密码。
46    const char *password = "123456";
47    Crypto_DataBlob passwordBlob = {
48        .data = reinterpret_cast<uint8_t *>(const_cast<char *>(password)),
49        .len = strlen(password)
50    };
51    ret = OH_CryptoKdfParams_SetParam(params, CRYPTO_KDF_KEY_DATABLOB, &passwordBlob);
52    if (ret != CRYPTO_SUCCESS) {
53        OH_CryptoKdfParams_Destroy(params);
54        return ret;
55    }
56
57    // 设置盐值。
58    const char *salt = "saltstring";
59    Crypto_DataBlob saltBlob = {
60        .data = reinterpret_cast<uint8_t *>(const_cast<char *>(salt)),
61        .len = strlen(salt)
62    };
63    ret = OH_CryptoKdfParams_SetParam(params, CRYPTO_KDF_SALT_DATABLOB, &saltBlob);
64    if (ret != CRYPTO_SUCCESS) {
65        OH_CryptoKdfParams_Destroy(params);
66        return ret;
67    }
68
69    // 设置Scrypt参数。
70    uint64_t n = 1024;  // CPU/内存开销参数。
71    uint64_t r = 8;     // 块大小参数。
72    uint64_t p = 16;    // 并行化参数。
73    uint64_t maxMem = 1067008;  // 最大内存限制(字节)。
74
75    Crypto_DataBlob nData = {
76        .data = reinterpret_cast<uint8_t *>(&n),
77        .len = sizeof(uint64_t)
78    };
79    Crypto_DataBlob rData = {
80        .data = reinterpret_cast<uint8_t *>(&r),
81        .len = sizeof(uint64_t)
82    };
83    Crypto_DataBlob pData = {
84        .data = reinterpret_cast<uint8_t *>(&p),
85        .len = sizeof(uint64_t)
86    };
87    Crypto_DataBlob maxMemData = {
88        .data = reinterpret_cast<uint8_t *>(&maxMem),
89        .len = sizeof(uint64_t)
90    };
91
92    ret = OH_CryptoKdfParams_SetParam(params, CRYPTO_KDF_SCRYPT_N_UINT64, &nData);
93    if (ret != CRYPTO_SUCCESS) {
94        OH_CryptoKdfParams_Destroy(params);
95        return ret;
96    }
97    ret = OH_CryptoKdfParams_SetParam(params, CRYPTO_KDF_SCRYPT_R_UINT64, &rData);
98    if (ret != CRYPTO_SUCCESS) {
99        OH_CryptoKdfParams_Destroy(params);
100        return ret;
101    }
102    ret = OH_CryptoKdfParams_SetParam(params, CRYPTO_KDF_SCRYPT_P_UINT64, &pData);
103    if (ret != CRYPTO_SUCCESS) {
104        OH_CryptoKdfParams_Destroy(params);
105        return ret;
106    }
107    ret = OH_CryptoKdfParams_SetParam(params, CRYPTO_KDF_SCRYPT_MAX_MEM_UINT64, &maxMemData);
108    if (ret != CRYPTO_SUCCESS) {
109        OH_CryptoKdfParams_Destroy(params);
110        return ret;
111    }
112
113    // 创建密钥派生函数对象。
114    OH_CryptoKdf *kdfCtx = nullptr;
115    ret = OH_CryptoKdf_Create("SCRYPT", &kdfCtx);
116    if (ret != CRYPTO_SUCCESS) {
117        OH_CryptoKdfParams_Destroy(params);
118        return ret;
119    }
120
121    // 派生密钥。
122    Crypto_DataBlob out = {0};
123    uint32_t keyLength = 32; // 生成32字节的密钥。
124    ret = OH_CryptoKdf_Derive(kdfCtx, params, keyLength, &out);
125    if (ret != CRYPTO_SUCCESS) {
126        OH_CryptoKdf_Destroy(kdfCtx);
127        OH_CryptoKdfParams_Destroy(params);
128        return ret;
129    }
130
131    printf("Derived key length: %u\n", out.len);
132
133    // 清理资源。
134    OH_Crypto_FreeDataBlob(&out);
135    OH_CryptoKdf_Destroy(kdfCtx);
136    OH_CryptoKdfParams_Destroy(params);
137    return CRYPTO_SUCCESS;
138}
139```