关于调用TCM SDK(TSM)接口加载用户密钥失败的解决办法

最近写程序,发现一个问题:为了调试方便,开发时程序是以普通应用程序方式运行的,也就是通过双击EXE文件进行开发、调试的。后来整合系统时,程序是以服务方式运行的,就发现了一个问题:原本开发时,调用TCM SDK(TSM)接口让TCM加载密钥时,是可以顺利加载的,但是程序以服务运行时,就加载不了,总报0x3020错误,检查tsm_error.h发现,20错误代码表示的是“TSM_E_PS_KEY_NOTFOUND”,原因是“The key cannot be found in the persistent storage database.”奇怪了,密钥明明是有的,为什么就加载不上呢?后来查了很多原因,最后发现加载不上的原因就是:TCM创建密钥时,是与当时创建密钥程序的运行方式、运行环境有关的,包括进程用户名、父进程用户名等等。

使用Process Explorer可以看到,所有的进程都是树型结构显示的,我们可以发现,通过双击运行的程序,它的父进程是explorer.exe(如下图1所示),而以服务运行的程序,其父进程是services.exe(如下图2所示),即便此服务程序以当前Windows用户为进程用户名而创建的进程,它父进程的父进程仍然是services.exe,所以这两种程序的运行环境是不一样的,造成调用TSM接口时加载的用户密钥,其用户空间是不一样的,于是就导致了上述密钥不存在的错误。

 

1

图 1 普通应用程序的父进程是explorer.exe

 

2

图 2 服务程序的父进程是services.exe

 

解决办法就是,密钥创建、密钥使用时,都改成调用系统空间的密钥:

Tspi_Context_GetKeyByUUID(hContext, TSM_PS_TYPE_SYSTEM, uuidSMS4Key, &hSMS4BindKey);

上面的Persistant Storage类型由“TSM_PS_TYPE_USER”改成“TSM_PS_TYPE_SYSTEM”就可以了。

创建密钥时也是一样:

Tspi_Context_RegisterKey(hContext, hSMS4BindKey, TSM_PS_TYPE_SYSTEM,
        uuidSMS4Key, TSM_PS_TYPE_SYSTEM, uuidSMKKey);

posted @ 2012-11-19 15:03  cxun  阅读(1088)  评论(0编辑  收藏  举报