PKCS#11 API-강좌1

PKCS#11 API-강좌1

PKCS#11 Module은 HSM(Hardware Security Module), Smart Card, Crypto Tokens(예를들면, USB Token)과 같은 Crypto Hardware를 Access하기 위한 API를 가지고 있는 Module이며, H/W Vendor가 제공하는 S/W Library 입니다. Cryptoki Module이라고도 불리는데, Cryptoki는 Cryptographic Token Interface를 줄여서 만든 글자라고 합니다.

​정리하면, PKCS#11 Module이란 PKCS#11 API를 가지고 있는 Module입니다.

PKCS#11 API 란 HSM 장비를 Call 하기 위해 만든 표준 I/F 중의 하나로, RSA사에서 표준화를 하여 제공하였으며(Ver2.2 와 Ver2.3 Draft), 지금은 표준화 작업이 OASIS community로 넘어간 상태입니다. HSM 장비를 제공하는 Vendor들은 Ver.2.2 를 기준으로 구현된 Provider(제공하는 S/W Library를 Provider라고 부름, HSM장비를 Access하기 위한 Agent S/W라고도 부름)를 제공하고 있기 때문에, Ver2.2를 기준으로 설명하고자 합니다.

​이 문서에는 PKCS#11 API 를 Cryptoki 로 표현하고 있으므로, Cryptoki 란 용어를 사용하여 설명하고자 합니다. Cryptoki 는 ANSI C type을 기준으로 기술되어 있습니다.

기본적인 개념(용어)을 중심으로 설명하고자 합니다.

Token 과 Slot

Cryptoki를 처음 디자인 할 때, Private-Key 와 같은 중요한 Cryptographic 정보를 Smart Card와 같이 이동이 가능한 Token(Cryptographic Token을 줄여서 Token이라 함)에 저장하는 것을 고려 하였기 때문에, Slot 이란 개념이 함께 생겼습니다. Smart Card(암호정보를 보관하는 Token의 한 종류)를 사용하려면, Smart Card Reader라는 장치에 Smart Card를 집어넣어 사용해야 합니다. Smart Card Reader 장치와 같은 역할을 하는 것을 Slot 이라고 부릅니다. 즉 Cryptoki 가 Token을 Access하려면, Slot에 Token이 장착되어 있어야 합니다. HSM 장비는 Token이 Slot에 장착된 장비라고 보면 됩니다. 즉 영문으로는 표현하면 “Slot with token present” 가 됩니다. HSM 장비 기준으로 보면 Slot과 Token이 1대1로 mapping이 되므로, Token이 곧 바로 Slot이 됩니다. 따라서 Cryptoki 에서는 HSM 장비를 Slot으로 보고 Access합니다. 즉 Cryptoki 관점에서 보면, HSM 장비는 한 개의 Slot 입니다. 여러 개의 Slot이 사용될 수 있으므로, Cryptoki는 Slot 번호로 Slot을 선택하여 사용합니다.

참고로, 당사에서 제공하는 KeyperPlus 장비는 하나의 장비에 최대 150개까지 Slot을 Define 할 수 있습니다. 대부분의 어플리케이션에서는 KeyperPlus를 하나의 Slot 으로만 사용한다고 합니다.

또한 다수의 Application이 다수의 Slot을 서로 공유하기도 하고 경쟁하기도 할 수 있으므로 Cryptoki Module의 개념은 아래 그림과 같습니다.

Token 과 Object

Cryptoki 관점에서 보면 Token은 Object를 저장하고 암호연산을 수행하는 디바이스입니다. Cryptoki는 Object를 3가지 종류로 분류합니다: Data Object, Key Object, Certificate Object

또 Object는 Life Time 과 Visibility에 따라 Token Object와 Session Object 2가지로 분류 됩니다.

Token Object는 Token 즉 HSM 장비에 저장되는 Object이며, Session Object는 Session 동안만 존재하는 Object 입니다. Session Object는 Cryptoki를 사용하는 서버의 메모리 어딘가에 일시적으로 존재하다가 Session이 Close 되면서 함께 사라지는 Object 입니다. Session Object는 해당 Session을 Create한 Application에서만 visible합니다.

Access 권리에 따라, Private Object와 Public Object로 나누어 집니다. 즉 Private Object는 인가된 사용자만 Access할 수 있습니다.

당사가 제공하는 KeyperPlus에서는 Key Object 중, Private-Key와 Secrete Key만 HSM 장비안에 저장하고, 나머지 Object(Public-Key Object, Certificate Object, Data Object)는 Cryptoki가 있는 서버의 특정 영역에 암호화되어 저장됩니다.

기술적으로 Public-Key Object에 대한 정보는 KeyperPlus내에 Private-Key와 함께 저장됩니다만, Public-Key는 보호하는 Key가 아니므로 Private-Key만 저장되어 있다고 표현하고 있습니다.

HSM 장비 안에 저장되는 Key를 Application Key라고 부릅니다.

KeyperPlus에서 Key가 생성될 때(Generation 또는 Import), “Key Policy” 를 정해 주어야 합니다. Key Policy에는 Key로 무엇을 할 수 있는 지(Sign, Encrypt, Decrypt 등), Export는 어떻게 되는 지(No Export, Wrapped only Export, Plain text Export 등)를 정해 주어야 합니다. Key가 생성되고 난 후에는 “Key Policy”는 변경 될 수 없습니다.

Session

Cryptoki와 Slot은 Session으로 연결됩니다. Cryptoki가 Token을 Access하기 위해서는 먼저 Token과 Session을 맺어야 합니다. 한 개 이상의 Session을 맺을 수 있습니다. Session이란 Cryptoki 와Token의 logical connection입니다.

Read/Write(R/W) Session이 있고, Read-Only Session이 있는 데, Token Object를 Access할 때의 기능을 정의하는 것입니다. 특별한 용도가 아니면, Token Object에 R/W 기능을 수행할 수 있는 R/W Session을 사용하신다고 보면 됩니다.

HSM 장비를 Access 하기 위해 Session을 Open할 때 C_OpenSession() 함수를 Call하는데, flag변수로 “CKF_SERIAL_SESSION|CKF_RW_SESSION” 값만 사용하면 됩니다. CKF_SERIAL_SESSION은 호환성을 유지하기 위하여 사용해야 한다고 합니다.

표준으로 제공하는 문서에 보면 자세하게 설명을 하고 있고 내용도 많지만, KeyperPlus와 같은 HSM 장비를 Access하는 Application을 cording하는 데는, 기본적인 개념만 이해하고 나머지는 무시를 해도 어려움이 없기 때문에 생략을 하고자 합니다(Session의 개념을 디자인한 분에게는 죄송스럽지만, 디자인하신 분의 의도를 정확히 안다고 해도, Cryptoki Coding을 더 잘 할 수 있는 것도 아니고, Session의 자세한 기능을 모른다고 해도 Cryptoki Coding을 하는 데 특별한 어려움이 없기 때문입니다). 하지만, Session의 다양한 기능을 필요로 하는 Application을 개발하시는 분들은 표준 문서에 기술된 내용을 자세히 이해하실 필요가 있다고 생각합니다.

Users : SO(Security Officer) 와 Normal User

Cryptoki는 두 가지 종류의 사용자를 인식합니다. Normal User만이 Token에 저장된 Object를 Access할 수 있습니다. 물론 Access하기 전에 적법한 사용자인지 Authentication(인증) 과정을 거칩니다. SO는 Token을 초기화 시키거나 Normal User의 PIN 번호를 지정하는 역할을 수행 합니다. 따라서 Token을 초기화 시키는 경우나 PIN 번호를 변경하는 경우가 아니면 SO는 필요하지 않습니다.

당사가 제공하는 KeyperPlus에서는 InitToken 이라는 Utility를 사용하여, 장비를 초기화 시킬 때, SO 와 Normal User에게 PIN 번호를 부여 합니다. 추후 Application에서 사용시는 Normal User의 PIN번호만 사용합니다.

Application

Cryptoki 관점에서 보면, 하나의 Application은 Single Address Space로 구성되어 지며, Single Process 입니다. 한 Application내에서는 다수의 Thread가 수행 가능합니다.

Application은 C_Initialize()를 Call함으로 Cryptoki Application이 되며, 암호 관련 연산을 수행 한 후, C_Finalize()를 Call함으로 일반 Application으로 돌아옵니다.

Application이 multi-threaded fashion으로 동작할 경우는, C_Initialize() 할 때, 4가지 방식의 multi-thread 방식 중 하나를 지정할 수 있습니다(자세한 내용은 참고자료).

C Language에서 File을 Access할 때, Handle을 가지고 다루듯이, Cryptoki 에서도 Session과 Object를 다룰 때 Handle을 사용합니다. Session Handle이란 Session을 identify하는 value이며, Object Handle 이란 Object를 identify하는 value 입니다.

Cryptoki API

General Purpose functions :

C_Initialize : initializes Cryptoki

C_Finalize : clean up miscellaneous Cryptokiassociated resources

C_GetInfo : obtains general information aboutCryptoki

C_GetFunctionList : obtains entry points of Cryptoki libraryfunctions

Slot and token management functions :

C_GetSlotList : obtains a list of slots in the system

C_GetSlotInfo : obtains information about a particular slot

C_GetTokenInfo : obtains information about a particular token

C_WaitForSlotEvent : waits for a slot event (token insertion, removal, etc.) to occur

C_GetMechanismList : obtains a list of mechanisms supported by a token

C_GetMechanismInfo : obtains information about a particular mechanism

C_InitToken : initializes a token

C_InitPIN : initializes the normal user’s PIN

C_SetPIN : modifies the PIN of the current user

Session management functions :

C_OpenSession : opens a connection between an application and a particular token or sets up an application callback for token insertion

C_CloseSession : closes a session

C_CloseAllSessions : closes all sessions with a token

C_GetSessionInfo : obtains information about the session

C_GetOperationState : obtains the cryptographic operations state of a session

C_SetOperationState : sets the cryptographic operations state of a session

C_Login : logs into a token

C_Logout : logs out from a token

Object management functions

C_CreateObject : creates an object

C_CopyObject : creates a copy of an object

C_DestroyObject : destroys an object

C_GetObjectSize : obtains the size of an object in bytes

C_GetAttributeValue : obtains an attribute value of an object

C_SetAttributeValue : modifies an attribute value of an object

C_FindObjectsInit : initializes an object search operation

C_FindObjects : continues an object search operation

C_FindObjectsFinal : finishes an object search operation

Encryption functions

C_EncryptInit : initializes an encryption operation

C_Encrypt : encrypts single-part data

C_EncryptUpdate : continues a multiple-part encryption operation

C_EncryptFinal : finishes a multiple-part encryption operation

Decryption functions

C_DecryptInit : initializes a decryption operation

C_Decrypt : decrypts single-part encrypted data

C_DecryptUpdate : continues a multiple-part decryption operation

C_DecryptFinal : finishes a multiple-part decryption operation

Message digesting functions

C_DigestInit : initializes a message-digesting operation

C_Digest : digests single-part data

C_DigestUpdate : continues a multiple-part digesting operation

C_DigestKey : digests a key

C_DigestFinal : finishes a multiple-part digesting operation

Signing and MACing functions

C_SignInit : initializes a signature operation

C_Sign signs : single-part data

C_SignUpdate : continues a multiple-part signature operation

C_SignFinal : finishes a multiple-part signature operation

C_SignRecoverInit : initializes a signature operation, where the data can be recovered from the signature

C_SignRecover signs : single-part data, where the data can be recovered from the signature

Functions for verifying signatures and MACs

C_VerifyInit : initializes a verification operation

C_Verify : verifies a signature on single-part data

C_VerifyUpdate : continues a multiple-part verification operation

C_VerifyFinal : finishes a multiple-part verification operation

C_VerifyRecoverInit : initializes a verification operation where the data is recovered from the signature

C_VerifyRecover : verifies a signature on single-part data, where the data is recovered from the signature

Dual-purpose cryptographic function

C_DigestEncryptUpdate : continues simultaneous multiple-part digesting and encryption operations

C_DecryptDigestUpdate : continues simultaneous multiple-part decryption and digesting operations

C_SignEncryptUpdate : continues simultaneous multiple-part signature and encryption operations

C_DecryptVerifyUpdate : continues simultaneous multiple-part decryption and verification operations

Key management functions

C_GenerateKey : generates a secret key

C_GenerateKeyPair : generates a public-key/private-key pair

C_WrapKey : wraps (encrypts) a key

C_UnwrapKey : unwraps (decrypts) a key

C_DeriveKey : derives a key from a base key

Random number generation functions

C_SeedRandom : mixes in additional seed material to the random number generator

C_GenerateRandom : generates random data

Parallel function management functions

C_GetFunctionStatus : legacy function which always returns CKR_FUNCTION_NOT_PARALLEL

C_CancelFunction : legacy function which always returns CKR_FUNCTION_NOT_PARALLEL

Callback function

application-supplied function to process notifications from Cryptoki

Last updated