1 密码设备应用接口在PKI应用技术体系框架中的位置
在公钥密码基础设施(PKI,Public Key Infrastructure)应用技术体系框架中,密码设备服务层由密码机、密码卡、智能密码终端等设备组成,通过密码设备应用接口向通用密码服务层提供基础密码服务,如下图所示。基础密码服务包括密钥生成、单一的密码运算、文件管理等的服务。

2 数据结构
2.1 设备信息
typedef struct DeviceInfo_st {
unsigned char IssuerName[40]; // 设备生产厂商名称
unsigned char DeviceName[16]; // 设备型号
unsigned char DeviceSerial[16]; // 设备编号,包含:日期(8字符)、批次号(3字符)、流水号(5字符)
unsigned int DeviceVersion; // 密码设备内部软件的版本号
unsigned int StandardVersion; // 密码设备支持的接口规范版本号
unsigned int AsymAlgAbility[2]; // 前4字节表示支持的算法,表示方法为非对称算法标识按位或的结果; 后4字节表示算法的最大模长,表示方法为支持的模长按位或的结果
unsigned int SymAlgAbility; // 所有支持的对称算法,表示方法为对称算法标识按位或运算结果
unsigned int HashAlgAbility; // 所有支持的杂凑算法,表示方法为杂凑算法标识按位或运算结果
unsigned int BufferSize; // 支持的最大文件存储空间(单位字节)
} DEVICEINFO;
2.2 密钥分类
2.2.1 设备密钥与用户密钥
设备密钥只能在设备初始化时生成或安装,用户密钥通过密码设备管理工具生成或安装。
设备密钥和用户密钥存放于密钥存储区,索引号从0开始检索,每个案引号对应一个签名密钥对和一个加密密钥对。
其中,索引号为0表示设备密钥。索引号从1开始表示用户密。
| 密钥对索引号 | 公钥 | 私钥 |
| 0x00 | 设备签名公钥 | 设备签名私钥 |
| 设备加密公钥 | 设备加密私钥 | |
| 0x01 | 用户签名公钥 | 用户签名私钥 |
| 用户加密公钥 | 用户加密私钥 | |
| ...... | ...... | ...... |
| ...... | ...... |
2.2.2 密钥加密密钥
密钥加密密钥通过密码设备管理工具生成或安装,密钥长度为128位,存放于密钥存储区,使用索引号从1开始。
| 密钥索引号 | 密钥加密密钥 |
| 0x01 | 密钥加密密钥 001 |
| ...... | ...... |
2.2.3 会话密钥
会话密钥使用设备接口函数生成或导人,会话密钥使用句柄检索。
2.3 RSA密钥数据结构
RSA密钥结构存储时顺序为从高到低,即密钥存放时从密钥结构数组的最高位开始,最高字节填在最高位,不足位填充数据0。
#define RSAref_MAX_BITS 2048
#define RSAref_MAX_LEN ((RSAref_MAX_BITS + 7) / 8) //256
#define RSAref_MAX_PBITS ((RSAref_MAX_BITS + 1) / 2) //1024
#define RSAref_MAX_PLEN ((RSAref_MAX_PBITS + 7)/ 8) //128
// RSA 公钥数据结构
typedef struct RSArefPublicKey_st {
unsigned int bits;
unsigned char m[RSAref_MAX_LEN];
unsigned char e[RSAref_MAX_LEN];
} RSArefPublicKey;
// RSA 私钥数据结构
typedef struct RSArefPrivateKey_st {
unsigned int bits;
unsigned char m[RSAref_MAX_LEN];
unsigned char e[RSAref_MAX_LEN];
unsigned char d[RSAref_MAX_LEN];
unsigned char prime[2][RSAref_MAX_PLEN];
unsigned char pexp[2][RSAref_MAX_PLEN];
unsigned char coef[RSAref_MAX_PLEN];
} RSArefPrivateKey;
2.4 ECC密钥数据结构
#define ECCref_MAX_BITS 512
#define ECCref_MAX_LEN ((ECCref_MAX_BITS+7) / 8)
// ECC 公钥数据结构
typedef struct ECCrefPublicKey_st {
unsigned int bits; // 密钥位长
unsigned char x[ECCref_MAX_LEN]; // 公钥 x 坐标
unsigned char y[ECCref_MAX_LEN]; // 公钥 y 坐标
} ECCrefPublicKey;
// ECC 私钥数据结构
typedef struct ECCrefPrivateKey_st {
unsigned int bits; // 密钥位长
unsigned char K[ECCref_MAX_LEN]; // 私钥
} ECCrefPrivateKey;
// ECC 加密数据结构
typedef struct ECCCipher_st {
unsigned char x[ECCref_MAX_LEN]; // X 分量
unsigned char y[ECCref_MAX_LEN]; // Y 分量
unsigned char M[32]; // 明文的杂凑值
unsigned int L; // 密文数据长度
unsigned char C[1]; // 密文数据
} ECCCipher;
// ECC 签名数据结构
typedef struct ECCSignature_st {
unsigned char r[ECCref_MAX_LEN]; // 签名的 r 部分
unsigned char s[ECCref_MAX_LEN]; // 签名的 s 部分
} ECCSignature;
2.5 ECC加密密钥对保护结构
密钥管理系统下发到设备中的 ECC加密密钥对使用以下结构表示。
typedef struct SDF_ENVELOPEDKEYBLOB {
unsigned long ulAsymmAlgID; //保护对称密钥的非对称算法标识
unsigned long ulSymmAlgID; //对称算法标识, 必须为ECB模式
ECCCIPHERBLOB ECCCipherBlob; //对称密钥密文
ECCPUBLICKEYBLOB PubKey; //加密密钥对的公钥
unsigned char cbEncryptedPrivKey[64]; //加密密钥对的私钥密文
} ENVELOPEDKEYBLOB, *PENVELOPEDKEYBLOB;
上述ECC加密密钥对保护结构中的对称密钥密文结构和加密密钥对公钥的结构为《GM/T 0016-2012 智能密码钥匙密码应用接口规范》中定义的结构,如下所示:
#define ECC_MAX_XCOORDINATE_BITS_LEN 512 // ECC算法X坐标的最大长度
#define ECC_MAX_YCOORDINATE_BITS_LEN 512 // ECC算法Y坐标的最大长度
// ECC 密文数据结构
typedef struct Struct_ECCCIPHERBLOB{
BYTE XCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8];
BYTE YCoordinate[ECC_MAX_YCOORDINATE_BITS_LEN/8];
BYTE Hash[32]; // 明文的杂凑值
ULONG CipherLen; // 密文的数据长度
BYTE Cipher[1]; // 密文数据,实际长度为 CipherLen
}ECCCIPHERBLOB, *PECCCIPHERBLOB;
// ECC 公钥数据结构
typedef struct Struct_ECCPUBLICKEYBLOB{
ULONG BitLen; // 模数的实际位长度, 必须是8的倍数
BYTE XCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8]; // 曲线上点的X坐标
BYTE YCoordinate[ECC_MAX_YCOORDINATE_BITS_LEN/8]; // 曲线上点的Y坐标
}ECCPUBLICKEYBLOB, *PECCPUBLICKEYBLOB;
同时,应注意与《GM/T 0016-2012 智能密码钥匙密码应用接口规范》中定义的ECC加密密钥对保护结构(如下所示)做区分。
typedef struct SKF_ENVELOPEDKEYBLOB{
ULONG Version; // 版本号,当前版本为1
ULONG ulSymmAlgID; // 对称算法标识,必须为ECB模式
ULONG ulBits; // 加密密钥对的密钥位长度
BYTE cbEncryptedPriKey[64]; // 加密密钥对的私钥的密文
ECCPUBLICKEYBLOB PubKey; // 加密密钥对的公钥
ECCCIPHERBLOB ECCCipherBlob; // 用保护公钥加密的对称密钥密文
}ENVELOPEDKEYBLOB, *PENVELOPEDKEYBLOB;
3 设备接口
以下接口涉及密码设备存储的密钥对索引值的起始索引值为1,最大为n,密码设备的实际存储容量决定n值。
3.1 设备管理类接口
// 打开设备
int SDF_OpenDevice(void** phDeviceHandle);
// 关闭密码设备, 并释放相关资源
int SDF_CloseDevice(void* hDeviceHandle);
// 创建与密码设备的会话
int SDF_OpenSession(void* hDeviceHandle, void** phSessionHandle);
// 关闭与密码设备已建立的会话, 并释放相关资源
int SDF_CloseSession(void* hSessionHandle);
// 获取密码设备能力描述
int SDF_GetDeviceInfo(
void* hSessionHandle,
DEVICEINFO *pstDeviceInfo);
// 获取指定长度的随机数
int SDF_GenerateRandom(
void* hSessionHandle,
unsigned int uiLength,
unsigned char* pucRandom);
// 获取密码设备内部存储的指定索引私钥的使用权
int SDF_GetPrivateKeyAccessRight(
void* hSessionHandle,
unsigned int uiKeyIndex,
unsigned char* pucPassword,
unsigned int uiPwdLength);
// 释放密码设备存储的指定索引私钥的使用授权
int SDF_ReleasePrivateKeyAccessRight(
void* hSessionHandle,
unsigned int uiKeyIndex);
3.1.1 设备打开关闭接口示例
int DevManage_OpenCloseDevice()
{
int rv, i;
void* devHandle = NULL;
rv = SDF_OpenDevice((HANDLE *)&devHandle);
if(rv != SDR_OK) {
printf("SDF_OpenDevice is error 0x%x\n", rv);
return rv;
}
rv = SDF_CloseDevice(devHandle);
if(rv != SDR_OK) {
printf("SDF_CloseDevice is error 0x%x\n", rv);
return rv;
}
return 0;
}
3.1.2 会话打开关闭接口示例
int DevManage_OpenCloseSession()
{
int rv,i = 0;
void* phSessionHandle;
void* devHandle;
rv = SDF_OpenDevice((HANDLE *)&devHandle);
if(rv != SDR_OK) {
printf("SDF_OpenDevice is error 0x%x\n", rv);
return rv;
}
rv = SDF_OpenSession(devHandle,(HANDLE *)&phSessionHandle);
if(rv != SDR_OK) {
printf("SDF_OpenSession is error 0x%x\n", rv);
goto err;
}
rv = SDF_CloseSession(phSessionHandle);
if(rv != SDR_OK) {
printf("SDF_CloseSession is error 0x%x\n", rv);
goto

本文围绕密码设备应用接口展开,介绍其在PKI应用技术体系框架中的位置,阐述了设备信息、密钥分类等数据结构,详细列举设备管理、密钥管理等各类接口示例,还说明了密码设备初始和就绪两个状态的要求及对应操作限制。
最低0.47元/天 解锁文章
1920





