---
title: 接口调用示例
description: "本章节介绍了SM2密钥管理接口的示例代码及编译运行步骤。"
url: https://www.hikunpeng.com/document/detail/zh/kunpengcctrustzone/cca/devg/Kunpeng_ommercialcryptography_16_0033.html
sourcePath: /source/zh/kunpengcctrustzone/cca/devg/Kunpeng_ommercialcryptography_16_0033.html
indexId: 056cc8ac6979e4cb285cbcefa902a506e3ada86cbf85f4c2d8f4d1a3aa58f80581
---
# 接口调用示例

本章节介绍了SM2密钥管理接口的示例代码及编译运行步骤。

#### 密钥管理接口示例

如下提供示例代码演示了上述接口的使用方式，以SM2用户密钥为例，包括密钥的创建、密钥标识码的修改、密钥访问权限路径添加与删除、导出导入密钥，删除密钥。

```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/sha.h>
#include "sdf.h"
#define MAX_KEY_FILE_SIZE (1024 * 1024)
#define EXPORT_SALT "123456789"
#define CA_PATH "./test_sdf"
#define USER_NAME "root"
#define PASSWD "Huawei123."
#define NEWPASSWD "Huawei321."
#define ALG_FLAG_OFFSET 20
int generate_key(void *session, unsigned int key_id, unsigned char *password)
{
int ret;
// sm2签名及加密密钥
unsigned int sign_info = SDF_SM2_SIGN << ALG_FLAG_OFFSET | key_id;
unsigned int enc_info = SDF_SM2_ENC << ALG_FLAG_OFFSET | key_id;
ret = ECM_GenerateKey(session, sign_info, password, strlen(password));
if (ret != SDR_OK) {
printf("ECM_GenerateKey sign key failed, ret = 0x%x\n", ret);
return ret;
}
ret = ECM_GenerateKey(session, enc_info, password, strlen(password));
if (ret != SDR_OK) {
printf("ECM_GenerateKey enc key failed, ret = 0x%x\n", ret);
return ret;
}
return ret;
}
int delete_key(void *session, unsigned int key_id)
{
int ret;
unsigned int sign_info = SDF_SM2_SIGN << ALG_FLAG_OFFSET | key_id;
unsigned int enc_info = SDF_SM2_ENC << ALG_FLAG_OFFSET | key_id;
ret = ECM_DeleteKey(session, sign_info);
if (ret != SDR_OK) {
printf("ECM_DeleteKey key_index %d failed, ret = 0x%x\n", key_id, ret);
return ret;
}
ret = ECM_DeleteKey(session, enc_info);
if (ret != SDR_OK) {
printf("ECM_DeleteKey key_index %d failed, ret = 0x%x\n", key_id, ret);
}
return ret;
}
int export_import_key(void *session, unsigned int key_id1, unsigned int key_id2)
{
int ret = -1;
uint8_t *key_data = NULL;
uint32_t key_data_len = MAX_KEY_FILE_SIZE;
unsigned int sign_key_info1 = SDF_SM2_SIGN << ALG_FLAG_OFFSET | key_id1;
unsigned int sign_key_info2 = SDF_SM2_SIGN << ALG_FLAG_OFFSET | key_id2;
unsigned int enc_key_info1 = SDF_SM2_ENC << ALG_FLAG_OFFSET | key_id1;
unsigned int enc_key_info2 = SDF_SM2_ENC << ALG_FLAG_OFFSET | key_id2;
key_data = (uint8_t *)malloc(key_data_len);
if (key_data == NULL) {
printf("malloc failed\n");
return -1;
}
// 导出导入签名密钥
ret = ECM_ExportKey(session, sign_key_info1, key_data, &key_data_len, EXPORT_SALT);
if (ret) {
printf("ECM_ExportKey sign key failed, ret = 0x%x, %d\n", ret, key_data_len);
goto free;
}
ret = ECM_ImportKey(session, sign_key_info2, key_data, key_data_len, EXPORT_SALT);
if (ret) {
printf("ECM_ImportKey sign key failed, ret = 0x%x\n", ret);
goto free;
}
// 导出导入加密密钥
ret = ECM_ExportKey(session, enc_key_info1, key_data, &key_data_len, EXPORT_SALT);
if (ret) {
printf("ECM_ExportKey enc key failed, ret = 0x%x, %d\n", ret, key_data_len);
goto free;
}
ret = ECM_ImportKey(session, enc_key_info2, key_data, key_data_len, EXPORT_SALT);
if (ret) {
printf("ECM_ImportKey enc key failed, ret = 0x%x\n", ret);
goto free;
}
free:
free(key_data);
return ret;
}
int change_passwd(void *session, unsigned int key_id, char *passwd, char *new_passwd)
{
int ret;
unsigned int sign_info = SDF_SM2_SIGN << ALG_FLAG_OFFSET | key_id;
unsigned int enc_info = SDF_SM2_ENC << ALG_FLAG_OFFSET | key_id;
ret = ECM_ChangePassword(session, sign_info, passwd, strlen(passwd), new_passwd, strlen(new_passwd));
if (ret != SDR_OK) {
printf("ECM_ChangePassword sign key failed, ret = 0x%x\n", ret);
return ret;
}
ret = ECM_ChangePassword(session, enc_info, passwd, strlen(passwd), new_passwd, strlen(new_passwd));
if (ret != SDR_OK) {
printf("ECM_ChangePassword sign key failed, ret = 0x%x\n", ret);
}
return ret;
}
void calculate_cainfo(const char *ca_path, const char *user_name, unsigned char hash[32])
{
char plan[256] = {0};
memcpy(plan, user_name, strlen(user_name));
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, ca_path, strlen(ca_path));
SHA256_Update(&sha256, plan, 256);
SHA256_Final(hash, &sha256);
for (size_t i = 0; i < 32; i++) {
printf("%02x", hash[i]);
}
printf("\n");
}
int main()
{
int ret = -1;
int key_idx1 = 1, key_idx2 = 2;
void *device = NULL, *session = NULL;
ret = SDF_OpenDevice(&device);
if (ret != SDR_OK) {
printf("sdf open device failed, ret = 0x%x\n", ret);
return ret;
}
ret = ECM_OpenSession(device, &session);
if (ret != SDR_OK) {
printf("sdf open session failed, ret = 0x%x\n", ret);
goto close;
}
ret = generate_key(session, key_idx1, PASSWD);
if (ret != SDR_OK) {
printf("generate_key failed, ret = 0x%x\n", ret);
goto close;
}
printf("generate key success\n");
// 修改密码
ret = change_passwd(session, key_idx1, PASSWD, NEWPASSWD);
if (ret != SDR_OK) {
printf("chage key passwd failed, ret = 0x%x\n", ret);
goto close;
}
printf("change passwd success\n");
// 导入密钥到key_idx2
ret = export_import_key(session, key_idx1, key_idx2);
if (ret != SDR_OK) {
printf("export_import_key failed, ret = 0x%x\n", ret);
goto close;
}
printf("export key %d, import to key %d success\n", key_idx1, key_idx2);
ret = delete_key(session, key_idx1);
if (ret != SDR_OK) {
printf("ECM_DeleteKey failed, ret = 0x%x\n", ret);
goto close;
}
ret = delete_key(session, key_idx2);
if (ret != SDR_OK) {
printf("ECM_DeleteKey failed, ret = 0x%x\n", ret);
goto close;
}
printf("delete key success\n");
close:
if (session != NULL) {
(void)SDF_CloseSession(session);
}
if (device != NULL) {
(void)SDF_CloseDevice(device);
}
return ret;
}
gcc -I/path/to/sdf.h/ test.c -lsdf  -lcrypto
```


#### 密钥使用接口示例

1. 下载本模块的接口头文件。

```
git clone https://gitcode.com/openeuler/itrustee_sdk.git
```


2. 在代码中引用sdf.h头文件，即可进行应用开发，以获取设备信息为例。

```
vim test_sdf.c
```


  创建test_sdf.c源文件，添加如下内容。

```
#include <stdio.h>
#include "sdf.h"
int main()
{
int ret = -1;
void *hDeviceHandle = NULL;
void *hSessionHandle = NULL;
DEVICEINFO info = {0};
ret = SDF_OpenDevice(&hDeviceHandle);
if (ret != SDR_OK) {
printf("sdf open device failed, ret = 0x%x\n", ret);
return ret;
}
ret = SDF_OpenSession(hDeviceHandle, &hSessionHandle);
if (ret != SDR_OK) {
printf("sdf open session failed, ret = 0x%x\n", ret);
return ret;
}
printf("sdf open device and session success\n");
ret = SDF_GetDeviceInfo(hSessionHandle, &info);
if (ret != SDR_OK) {
printf("sdf get device info failed, ret = 0x%x\n", ret);
return ret;
}
printf("sdf get device info success\n");
printf("Device Name: %s\n", info.DeviceName);
return 0;
}
```


3. 完毕后可参考如下命令编译。

```
gcc test_sdf.c -lsdf -ldl  -I/path/to/itrustee_sdk/include/SDF/ -o test_sdf
```


4. 执行应用，可成功打印设备名称。

```
./test_sdf
```
