예제

Prev Next

VPC 환경에서 이용 가능합니다.

마스터 키와 자식 키를 파생하는 예제를 통해 BIP32 메커니즘을 구현하는 방법을 실습할 수 있습니다.

참고

BIP32 메커니즘 구현은 Thales 공식 문서를 기반으로 작성되었습니다. 사용 가이드에서 안내하는 내용 외에 더 많은 내용을 살펴보려면 BIP32 Mechanism Support and Implementation을 참고해 주십시오.

실습을 시작하기 전, 다음의 전제 조건을 준수해 주십시오.

  • 네이버 클라우드 플랫폼 콘솔에서 HSM 생성, 연결 생성 완료
  • /usr/safenet/lunaclient/samples/source 경로의 main.c 파일을 수정/빌드한 상태로 실습을 수행해야 하므로 main.c 파일을 다운로드
  • 실습 서버의 사양: centos-7.8-64, [Standard] 2vCPU, 4GB Mem [g1]

키를 파생하기 전에 다음의 절차를 따라 테스트 환경을 설정해 주십시오.

  1. /usr/safenet/lunaclient/samples/source의 기존 main.c를 다운로드한 코드로 교체해 주십시오.
    • 기존 main.c는 백업해 주십시오.
  2. 코드 12번째 라인의 PASSWORD 변수에 슬롯의 비밀번호(암호화 관리자 비밀번호)를 입력해 주십시오.
  3. make -f Makefile.linux.32로 빌드해 주십시오.
  4. p11Sample을 실행해 주십시오.

마스터 키 페어를 파생하는 예제는 다음과 같습니다. 파생에 필요한 hSeedKey는 HSM에서 AES 키를 생성하고 C_UnwrapKey()를 실행하여 사용하였습니다.

CK_RV DeriveMasterKey (CK_SESSION_HANDLE hSession,
	CK_OBJECT_HANDLE* hPubKey,
	CK_OBJECT_HANDLE* hPriKey
	)
{
	CK_RV rv=CKR_OK;
	CK_BBOOL bToken;
	CK_BBOOL bTrue=CK_TRUE;
	CK_BBOOL bFalse=CK_FALSE;
	CK_CHAR pbLabel[] = "BIP32 MasterKey Derive";

	CK_ATTRIBUTE pubTemplate[] =
	{
	   {CKA_TOKEN,             &bToken,      sizeof(bToken)},
	   {CKA_PRIVATE,           &bTrue,       sizeof(bTrue)},
	   {CKA_DERIVE,            &bTrue,       sizeof(bTrue)},
	   {CKA_MODIFIABLE,        &bTrue,       sizeof(bTrue)},
	   {CKA_LABEL,             pbLabel,      strlen(pbLabel)},
	};
	CK_ATTRIBUTE privTemplate[] =
	{
	   {CKA_TOKEN,             &bToken,      sizeof(bToken)},
	   {CKA_PRIVATE,           &bTrue,       sizeof(bTrue)},
	   {CKA_SENSITIVE,         &bTrue,       sizeof(bTrue)},
	   {CKA_DERIVE,            &bTrue,       sizeof(bTrue)},
	   {CKA_EXTRACTABLE,       &bFalse,       sizeof(bFalse)},
	   {CKA_MODIFIABLE,        &bTrue,       sizeof(bTrue)},
	   {CKA_LABEL,             pbLabel,      strlen(pbLabel)},
	};


	CK_BIP32_MASTER_DERIVE_PARAMS mechParams;
	mechParams.pPublicKeyTemplate = pubTemplate;
	mechParams.ulPublicKeyAttributeCount = ARRAY_SIZE(pubTemplate);
	mechParams.pPrivateKeyTemplate = privTemplate;
	mechParams.ulPrivateKeyAttributeCount =  ARRAY_SIZE(privTemplate);

	CK_MECHANISM mechanism = {CKM_BIP32_MASTER_DERIVE, &mechParams, sizeof(mechParams)};

	rv = P11Functions->C_DeriveKey(hSession, &mechanism, hUnwrappedKey, NULL, 0, NULL);
    if (rv != CKR_OK)
        {
                printf("DeriveMasterKey rv= 0x%lx\n", rv);
                goto doneDeriveMasterKey;
        }
	// fail if rv != CKR_OK
    printf("DeriveMasterKey Done\n");
	*hPubKey = mechParams.hPublicKey;
	*hPriKey = mechParams.hPrivateKey;

	doneDeriveMasterKey:
	return rv;
}
Plain text

하위 리프 키를 파생하는 예제는 다음과 같습니다.

CK_RV DeriveChildKeyPair(
	CK_SESSION_HANDLE hPrivateSession,
	CK_OBJECT_HANDLE hParent,
	CK_OBJECT_HANDLE* hPubKey,
	CK_OBJECT_HANDLE* hPriKey
	) {
		CK_RV retCode = CKR_OK;
		CK_BBOOL bToken;
		CK_BBOOL bTrue=CK_TRUE;
		CK_BBOOL bFalse=CK_FALSE;
		CK_OBJECT_HANDLE tmpHandle;
		CK_CHAR pbLabel[] = "BIP32 Childkey Derive";

		CK_ATTRIBUTE pubKeyTemplate[] = {
		   {CKA_TOKEN,             &bToken,      sizeof(bToken)},
		   {CKA_PRIVATE,           &bTrue,       sizeof(bTrue)},
		   {CKA_ENCRYPT,           &bTrue,       sizeof(bTrue)},
		   {CKA_VERIFY,            &bTrue,       sizeof(bTrue)},
		   {CKA_MODIFIABLE,        &bTrue,       sizeof(bTrue)},
		   {CKA_LABEL,             pbLabel,      strlen(pbLabel)},
		};

		CK_ATTRIBUTE priKeyTemplate[] = {
		   {CKA_TOKEN,             &bToken,      sizeof(bToken)},
		   {CKA_PRIVATE,           &bTrue,       sizeof(bTrue)},
		   {CKA_SENSITIVE,         &bTrue,       sizeof(bTrue)},
		   {CKA_SIGN,              &bTrue,       sizeof(bTrue)},
		   {CKA_DECRYPT,           &bTrue,       sizeof(bTrue)},
		   {CKA_MODIFIABLE,        &bTrue,       sizeof(bTrue)},
		   {CKA_LABEL,             pbLabel,      strlen(pbLabel)},
		};

		CK_ULONG path[] = {
			CKF_BIP32_HARDENED | CKG_BIP44_PURPOSE,
			CKF_BIP32_HARDENED | CKG_BIP44_COIN_TYPE_BTC,
			CKF_BIP32_HARDENED | 1,
			CKG_BIP32_EXTERNAL_CHAIN,
			0
		};

	CK_BIP32_CHILD_DERIVE_PARAMS mechParams;
	mechParams.pPublicKeyTemplate = pubKeyTemplate;
	mechParams.ulPublicKeyAttributeCount = ARRAY_SIZE(pubKeyTemplate);
	mechParams.pPrivateKeyTemplate = priKeyTemplate;
	mechParams.ulPrivateKeyAttributeCount = ARRAY_SIZE(priKeyTemplate);
	mechParams.pulPath = path;
	mechParams.ulPathLen = ARRAY_SIZE(path);
	CK_MECHANISM mechanism = {CKM_BIP32_CHILD_DERIVE, &mechParams, sizeof(mechParams)};
	printf("Derive Child\n");
	retCode = P11Functions->C_DeriveKey(hPrivateSession, &mechanism, hParent, NULL, 0, NULL);
        if (retCode != CKR_OK)
        {
                printf("DeriveChildKeyPair retCode 0x%lx\n", retCode);
                goto DeriveChildKeyPair;
        }
	// fail if rv != CKR_OK
    printf("DeriveChildKeyPair Done\n");
	*hPubKey = mechParams.hPublicKey;
	*hPriKey = mechParams.hPrivateKey;

	DeriveChildKeyPair:
		return retCode;
}
Plain text

제공되는 유틸리티인 ckdemo를 통해 파생된 하위 리프 키를 확인하는 방법은 다음과 같습니다.

  1. ckdemo를 실행해 주십시오.
    • Linux 서버: cd /usr/safenet/lunaclient/bin 입력 > ./ckdemo 입력
    • Windows 서버: 클라이언트 설치 경로로 이동(C:\Program Files\SafeNet\LunaClient) > ckdemo 실행 파일 더블 클릭
  2. 옵션 입력란에 1을 입력하여 Open Session을 실행해 주십시오.
    Enter your choice : 1
    
    Status: Doing great, no errors (CKR_OK)
    
    Plain text
  3. 옵션 입력란에 3을 입력하여 Login을 실행해 주십시오.
    Enter your choice : 3
    Partition SO            [0]
    Crypto Officer          [1]
    Crypto User             [2]: 1
    Enter PIN            : ***********
    
    Status: Doing great, no errors (CKR_OK)
    
    Plain text
  4. 옵션 입력란에 27을 입력하여 Display Object를 실행해 주십시오.
    • 로그인한 계정의 권한으로 볼 수 있는 모든 객체가 표시됩니다.
    • 테스트에서 생성한 Childkey label을 확인할 수 있습니다.
    • 개체별 자세한 내용을 보려면 핸들 입력값에 0이 아닌 핸들의 번호를 입력해 주십시오.
    Enter your choice : 27
    
    Enter handle of object to display (0 to list available objects) : 0
    
    Handle        175 (0x000000af) -- label: BIP32 Childkey Derive
    Handle        158 (0x0000009e) -- label: BIP32 Childkey Derive
    Handle        153 (0x00000099) -- label: BIP32 Seed
    Handle        150 (0x00000096) -- label: AES Encryption Key
    Handle 4293918721 (0xfff00001) -- label: Clock
    Handle 4293918722 (0xfff00002) -- label: Monotonic Counter
    Handle 4293918720 (0xfff00000) -- label: Partition SO
    Handle 4293918723 (0xfff00003) -- label: Crypto Officer
    Handle 4293918724 (0xfff00004) -- label: Crypto User
    
    Number of objects found = 9
    
    Plain text