Files

378 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Cryptoki 库概述
Solaris [加密](https://so.csdn.net/so/search?q=%E5%8A%A0%E5%AF%86&spm=1001.2101.3001.7020)框架中的用户级应用程序通过 libpkcs11.so 模块中所提供的 cryptoki 库来访问 PKCS #11 函数。pkcs11_softtoken.so 模块是由 Sun Microsystems, Inc. 提供的 PKCS #11 软令牌实现,用于提供加密机制。软令牌插件是缺省的机制源。加密机制还可以通过第三方插件提供。
本节列出了软令牌所支持的 PKCS #11 函数和返回值,返回代码根据插入到[框架](https://so.csdn.net/so/search?q=%E6%A1%86%E6%9E%B6&spm=1001.2101.3001.7020)中的提供者而异。本节还介绍了一些常见的函数。有关 cryptoki 库中所有元素的完整说明,请参阅相应的手册页或[http://www.rsasecurity.com/rsalabs/pkcs/pkcs-11](http://www.rsasecurity.com/rsalabs/pkcs/pkcs-11)。
### PKCS #11 函数列表
下面列出了 Solaris 加密框架中的 pkcs11_softtoken.so 所支持的 PKCS #11 函数类别以及相关函数:
- **通用**-**C_Initialize()**、**C_Finalize()**、**C_GetInfo()** 和 **C_GetFunctionList()**
- **会话管理**-**C_OpenSession()**、**C_CloseSession()**、**C_GetSessionInfo()**、**C_CloseAllSessions()**、**C_Login()**和 **C_Logout()**
- **插槽和令牌管理**-**C_GetSlotList()**、**C_GetSlotInfo()**、**C_GetMechanismList()**、**C_GetMechanismInfo()** 和**C_SetPIN()**
- **加密和解密**-**C_EncryptInit()**、**C_Encrypt()**、**C_EncryptUpdate()**、**C_EncryptFinal()**、**C_DecryptInit()**、**C_Decrypt()**、**C_DecryptUpdate()**和 **C_DecryptFinal()**
- **消息摘要**-**C_DigestInit()**、**C_Digest()**、**C_DigestKey()**、**C_DigestUpdate()** 和**C_DigestFinal()**
- **MAC 的签名和应用**-**C_Sign()**、**C_SignInit()**、**C_SignUpdate()**、**C_SignFinal()**、**C_SignRecoverInit()** 和**C_SignRecover()**
- **签名检验**-**C_Verify()**、**C_VerifyInit()**、**C_VerifyUpdate()**、**C_VerifyFinal()**、**C_VerifyRecoverInit()**和 **C_VerifyRecover()**
- **双重用途加密函数**-**C_DigestEncryptUpdate()**、**C_DecryptDigestUpdate()**、**C_SignEncryptUpdate()** 和**C_DecryptVerifyUpdate()**
- **随机数生成**-**C_SeedRandom()** 和 **C_GenerateRandom()**
- **对象管理**-**C_CreateObject()**、**C_DestroyObject()**、**C_CopyObject()**、**C_FindObjects()**、**C_FindObjectsInit()**、**C_FindObjectsFinal()**、**C_GetAttributeValue()**和 **C_SetAttributeValue()**
- **密钥管理**-**C_GenerateKey()**、**C_GenerateKeyPair()** 和 **C_DeriveKey()**
### 使用 PKCS #11 的函数
本节提供了以下使用 PKCS #11 的函数的说明:
- [PKCS #11 函数: **C_Initialize()**](http://docs.sun.com/app/docs/doc/819-7056/6n91eac56?l=zh&a=view#chapter2-9d)
- [PKCS #11 函数: **C_GetInfo()**](http://docs.sun.com/app/docs/doc/819-7056/6n91eac56?l=zh&a=view#chapter2-7)
- [PKCS #11 函数: **C_GetSlotList()**](http://docs.sun.com/app/docs/doc/819-7056/6n91eac56?l=zh&a=view#chapter2-9)
- [PKCS #11 函数: **C_GetTokenInfo()**](http://docs.sun.com/app/docs/doc/819-7056/6n91eac56?l=zh&a=view#chapter2-9a)
- [PKCS #11 函数: **C_OpenSession()**](http://docs.sun.com/app/docs/doc/819-7056/6n91eac56?l=zh&a=view#chapter2-9f)
- [PKCS #11 函数: **C_GetMechanismList()**](http://docs.sun.com/app/docs/doc/819-7056/6n91eac56?l=zh&a=view#chapter2-9b)
---
注 –
所有的 PKCS #11 函数都可以从 libpkcs11.so 库中获取,不必使用 **C_GetFunctionList()** 函数来获取可用函数的列表。
---
#### PKCS #11 函数: **C_Initialize()**
**C_Initialize()** 可用于初始化 PKCS #11 库。**C_Initialize()** 使用以下语法:
C_Initialize(CK_VOID_PTR pInitArgs);
pInitArgs 是空值 NULL_PTR 或是指向 CK_C_INITIALIZE_ARGS 结构的指针。通过 NULL_PTR,该库可以将 Solaris 互斥锁用作锁定原语,在多个线程之间仲裁对内部共享结构的访问。请注意,Solaris 加密框架不接受互斥锁。由于cryptoki 库的此实现可以安全高效地处理多线程,因此建议使用 NULL_PTR。应用程序还可以使用 pInitArgs 来设置诸如 CKF_LIBRARY_CANT_CREATE_OS_THREADS 之类的标志。**C_Finalize()** 表示应用程序使用 PKCS #11 库结束会话。
---
注 –
**C_Finalize()** 绝不应当通过库进行调用。按照惯例,应用程序负责调用 **C_Finalize()** 来关闭会话。
---
除了 CKR_FUNCTION_FAILED、CKR_GENERAL_ERROR、CKR_HOST_MEMORY 和 CKR_OK 以外,**C_Initialize()** 还会使用以下返回值:
- CKR_ARGUMENTS_BAD
- CKR_CANT_LOCK
- CKR_CRYPTOKI_ALREADY_INITIALIZED-此错误不是致命的。
#### PKCS #11 函数: **C_GetInfo()**
**C_GetInfo()** 使用的是有关 cryptoki 库的制造商和版本信息。**C_GetInfo()** 使用以下语法:
C_GetInfo(CK_INFO_PTR pInfo);
**C_GetInfo()** 会返回以下值:
- cryptokiVersion = 2, 11
- manufacturerID = Sun Microsystems, Inc.
除了 CKR_FUNCTION_FAILED、CKR_GENERAL_ERROR、CKR_HOST_MEMORY 和 CKR_OK 以外,**C_GetInfo()** 还可以获取以下返回值:
- CKR_ARGUMENTS_BAD
- CKR_CRYPTOKI_NOT_INITIALIZED
#### PKCS #11 函数: **C_GetSlotList()**
**C_GetSlotList()** 使用的是可用插槽的列表。如果除了 pkcs11_softtoken.so 以外尚未安装任何其他加密提供者,则 **C_GetSlotList()** 仅返回缺省插槽。**C_GetSlotList()** 使用以下语法:
C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList,
CK_ULONG_PTR pulCount);
如果 tokenPresent 设置为 TRUE,则会将搜索限制在那些存在令牌的插槽。
如果 pSlotList 设置为 NULL_PTR,则 **C_GetSlotlist()** 仅返回插槽的数量。pulCount 是指向用于接收插槽计数的位置的指针。
如果 pSlotList 指向用于接收插槽的缓冲区,则 *pulCount 将设置为 CK_SLOT_ID 元素的最大预期数量。在返回时,*pulCount 将设置为 CK_SLOT_ID 元素的实际数量。
通常,PKCS #11 应用程序会调用 **C_GetSlotList()** 两次。第一次调用 **C_GetSlotList()** 用于获取进行内存分配的插槽数量,第二次调用 **C_GetSlotList()** 用于获取插槽。
除了 CKR_FUNCTION_FAILED、CKR_GENERAL_ERROR、CKR_HOST_MEMORY 和 CKR_OK 以外,**C_GetSlotlist()** 还可以获取以下返回值:
- CKR_ARGUMENTS_BAD
- CKR_BUFFER_TOO_SMALL
- CKR_CRYPTOKI_NOT_INITIALIZED
#### PKCS #11 函数: **C_GetTokenInfo()**
**C_GetTokenInfo()** 可用于获取有关特定令牌的信息。**C_GetTokenInfo()** 使用以下语法:
C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo);
slotID 用于标识令牌的插槽。slotID 必须是由 **C_GetSlotList()** 返回的有效 ID。pInfo 是指向用于接收令牌信息的位置的指针。
如果 pkcs11_softtoken.so 是所安装的唯一提供者,则 **C_GetTokenInfo()** 将返回以下字段和值:
- 标记-Sun Software PKCS#11 软令牌。
- 标志-CKF_DUAL_CRYPTO_OPERATIONS、CKF_TOKEN_INITIALIZED、CKF_RNG、CKF_USER_PIN_INITIALIZED 和CKF_LOGIN_REQUIRED,这些标志设置为 1。
- ulMaxSessionCount-设置为 CK_EFFECTIVELY_INFINITE。
- ulMaxRwSessionCount-设置为 CK_EFFECTIVELY_INFINITE。
- ulMaxPinLen-设置为 256。
- ulMinPinLen-设置为 1。
- ulTotalPublicMemory-设置为 CK_UNAVAILABLE_INFORMATION。
- ulFreePublicMemory-设置为 CK_UNAVAILABLE_INFORMATION。
- ulTotalPrivateMemory-设置为 CK_UNAVAILABLE_INFORMATION。
- ulFreePrivateMemory-设置为 CK_UNAVAILABLE_INFORMATION。
除了 CKR_FUNCTION_FAILED、CKR_GENERAL_ERROR、CKR_HOST_MEMORY 和 CKR_OK 以外,**C_GetSlotlist()** 还可以获取以下返回值:
- CKR_ARGUMENTS_BAD
- CKR_BUFFER_TOO_SMALL
- CKR_CRYPTOKI_NOT_INITIALIZED
- CKR_SLOT_ID_INVALID
以下返回值与具有硬件令牌的插件相关:
- CKR_DEVICE_ERROR
- CKR_DEVICE_MEMORY
- CKR_DEVICE_REMOVED
- CKR_TOKEN_NOT_PRESENT
- CKR_TOKEN_NOT_RECOGNIZED
#### PKCS #11 函数: **C_OpenSession()**
应用程序可使用 **C_OpenSession()** 来启动特定插槽中具有特定令牌的加密会话。**C_OpenSession()** 使用以下语法:
C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication,
CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession);
slotID 用于标识插槽。flags 用于指示会话是只读的还是可读写的。pApplication 是应用程序所定义的用于回调的指针。Notify 用于存放可选回调函数的地址。phSession 是指向会话句柄的位置的指针。
除了 CKR_FUNCTION_FAILED、CKR_GENERAL_ERROR、CKR_HOST_MEMORY 和 CKR_OK 以外,**C_OpenSession()** 还可以获取以下返回值:
- CKR_ARGUMENTS_BAD
- CKR_CRYPTOKI_NOT_INITIALIZED
- CKR_SLOT_ID_INVALID
- CKR_TOKEN_WRITE_PROTECTED-随受写保护的令牌出现。
以下返回值与具有硬件令牌的插件相关:
- CKR_DEVICE_ERROR
- CKR_DEVICE_MEMORY
- CKR_DEVICE_REMOVED
- CKR_SESSION_COUNT
- CKR_SESSION_PARALLEL_NOT_SUPPORTED
- CKR_SESSION_READ_WRITE_SO_EXISTS
- CKR_TOKEN_NOT_PRESENT
- CKR_TOKEN_NOT_RECOGNIZED
#### PKCS #11 函数: **C_GetMechanismList()**
**C_GetMechanismList()** 可用于获取指定令牌所支持的机制类型的列表。**C_GetMechanismList()** 使用以下语法:
C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList,
CK_ULONG_PTR pulCount);
slotID 用于标识令牌的插槽。pulCount 是指向用于接收机制数量的位置的指针。 如果 pMechanismList 设置为 NULL_PTR,则 *pulCount 将返回机制的数量。否则,必须将 *pulCount 设置为列表的大小,pMechanismList 必须指向用于存放列表的缓冲区。
如果已插入 PKCS #11 软令牌,则 **C_GetMechanismList()** 将返回以下列出的支持的机制:
- CKM_AES_CBC
- CKM_AES_CBC_PAD
- CKM_AES_ECB
- CKM_AES_KEY_GEN
- CKM_DES_CBC
- CKM_DES_CBC_PAD
- CKM_DES_ECB
- CKM_DES_KEY_GEN
- CKM_DES_MAC
- CKM_DES_MAC_GENERAL
- CKM_DES3_CBC
- CKM_DES3_CBC_PAD
- CKM_DES3_ECB
- CKM_DES3_KEY_GEN
- CKM_DH_PKCS_DERIVE
- CKM_DH_PKCS_KEY_PAIR_GEN
- CKM_DSA
- CKM_DSA_KEY_PAIR_GEN
- CKM_DSA_SHA_1
- CKM_MD5
- CKM_MD5_KEY_DERIVATION
- CKM_MD5_RSA_PKCS
- CKM_MD5_HMAC
- CKM_MD5_HMAC_GENERAL
- CKM_PBE_SHA1_RC4_128
- CKM_PKCS5_PBKD2
- CKM_RC4
- CKM_RC4_KEY_GEN
- CKM_RSA_PKCS
- CKM_RSA_X_509
- CKM_RSA_PKCS_KEY_PAIR_GEN
- CKM_SHA_1
- CKM_SHA_1_HMAC_GENERAL
- CKM_SHA_1_HMAC
- CKM_SHA_1_KEY_DERIVATION
- CKM_SHA_1_RSA_PKCS
- CKM_SSL3_KEY_AND_MAC_DERIVE
- CKM_SSL3_MASTER_KEY_DERIVE
- CKM_SSL3_MASTER_KEY_DERIVE_DH
- CKM_SSL3_MD5_MAC
- CKM_SSL3_PRE_MASTER_KEY_GEN
- CKM_SSL3_SHA1_MAC
- CKM_TLS_KEY_AND_MAC_DERIVE
- CKM_TLS_MASTER_KEY_DERIVE
- CKM_TLS_MASTER_KEY_DERIVE_DH
- CKM_TLS_PRE_MASTER_KEY_GEN
除了 CKR_FUNCTION_FAILED、CKR_GENERAL_ERROR、CKR_HOST_MEMORY 和 CKR_OK 以外,**C_GetSlotlist()** 还使用以下返回值:
- CKR_ARGUMENTS_BAD
- CKR_BUFFER_TOO_SMALL
- CKR_CRYPTOKI_NOT_INITIALIZED
- CKR_SLOT_ID_INVALID
以下返回值与具有硬件令牌的插件相关:
- CKR_DEVICE_ERROR
- CKR_DEVICE_MEMORY
- CKR_DEVICE_REMOVED
- CKR_TOKEN_NOT_PRESENT
- CKR_TOKEN_NOT_RECOGNIZED
### 扩展的 PKCS #11 函数
除了标准的 PKCS #11 函数以外,Solaris 加密框架还附带了两个便利函数:
- [扩展的 PKCS #11 函数: **SUNW_C_GetMechSession()**](http://docs.sun.com/app/docs/doc/819-7056/6n91eac56?l=zh&a=view#efuser-5)
- [扩展的 PKCS #11 函数: SUNW_C_KeyToObject](http://docs.sun.com/app/docs/doc/819-7056/6n91eac56?l=zh&a=view#efuser-6)
#### 扩展的 PKCS #11 函数: **SUNW_C_GetMechSession()**
**SUNW_C_GetMechSession()** 是一个便利函数,用于初始化 Solaris 加密框架。该函数随后会使用指定的机制启动会话。**SUNW_C_GetMechSession()** 使用以下语法:
SUNW_C_GetMechSession(CK_MECHANISM_TYPE mech, C/
K_SESSION_HANDLE_PTR hSession)
mech 参数用于指定要使用的机制。hSession 是指向会话位置的指针。
**SUNW_C_GetMechSession()** 在内部调用 **C_Initialize()** 以初始化 cryptoki库。**SUNW_C_GetMechSession()** 接着会使用指定的机制调用 **C_GetSlotList()** 和**C_GetMechanismInfo()**,在可用插槽中搜索令牌。如果找到了机制,**SUNW_C_GetMechSession()** 会调用**C_OpenSession()** 来打开会话。
**SUNW_C_GetMechSession()** 只需要调用一次。不过,多次调用 **SUNW_C_GetMechSession()** 也不会造成任何问题。
#### 扩展的 PKCS #11 函数: SUNW_C_KeyToObject
**SUNW_C_KeyToObject()** 可用于创建私钥对象。调用程序必须指定要使用的机制以及原始密钥数据。**SUNW_C_KeyToObject()** 可在内部确定指定机制的密钥类型。通用密钥对象是通过 **C_CreateObject()** 创建的。**SUNW_C_KeyToObject()** 接着会调用 **C_GetSessionInfo()** 和 **C_GetMechanismInfo()** 来获取插槽和机制。**C_SetAttributeValue()** 随后会根据机制的类型为密钥对象设置属性标志。