密码设备(一):应用接口规范

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

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
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值