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", ¶ms); 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```