VPC 환경에서 이용 가능합니다.
키를 생성하거나 가져오고 내보낼 때 사용되는 샘플 코드를 설명합니다.
마스터 키 페어 파생
권한이 없는 사용자가 체인 코드를 볼 수 없도록 마스터 공개 및 개인 키의 CKA_PRIVATE
을 TRUE
로 설정해 주십시오. 마스터 키는 키 파생 시에만 사용해야 합니다. 템플릿에 속성이 없는 경우 공개/개인 키의 버전 바이트 기본값은 0x0488B21E/0x0488ADE4
이며, 이는 메인 비트코인 네트워크의 키에 대한 BIP32에 명시된 값입니다.
마스터 키 페어를 파생하는 샘플 코드는 다음과 같습니다. 파생이 완료되면 새로운 키 핸들이 pubKey
및 privKey
에 저장됩니다.
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_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)};
CK_RV rv = C_DeriveKey(hSession, &mechanism, hSeedKey, NULL, 0, NULL);
// fail if rv != CKR_OK
CK_OBJECT_HANDLE pubKey = mechanism.hPublicKey;
CK_OBJECT_HANDLE privKey = mechanism.hPrivateKey;
하위 리프 키 파생
권한이 없는 사용자가 체인 코드를 볼 수 없도록 마스터 공개 및 개인 키의 CKA_PRIVATE
을 TRUE
로 설정해 주십시오. 하위 리프 키(키 트리 최하단에 위치한 키)는 파생에 사용할 수 없으며 서명, 확인, 암호화 및 복호화에 사용해야 합니다. 부모 자식 키를 사용하려면 파생 속성을 설정해야 합니다. 템플릿에 속성이 없는 경우 공개/개인 키의 버전 바이트 기본값은 0x0488B21E/0x0488ADE4
이며, 이는 메인 비트코인 네트워크의 키에 대한 BIP32에 명시된 값입니다.
하위 리프 키를 파생하는 샘플 코드는 다음과 같습니다. 파생이 완료되면 새로운 키 핸들이 pubKey
및 privKey
에 저장됩니다. CK_ULONG path
는 BIP44 규약을 따르는 키 페어를 생성하고, BTC를 수신할 때 사용될 수 있습니다.
CK_ATTRIBUTE pubTemplate[] =
{
{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 privTemplate[] =
{
{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_MASTER_DERIVE_PARAMS mechParams;
mechParams.pPublicKeyTemplate = pubTemplate;
mechParams.ulPublicKeyAttributeCount = ARRAY_SIZE(pubTemplate);
mechParams.pPrivateKeyTemplate = privTemplate;
mechParams.ulPrivateKeyAttributeCount = ARRAY_SIZE(privTemplate);
mechParams.pulPath = path;
mechParams.ulPathLen = ARRAY_SIZE(path);
CK_MECHANISM mechanism = {CKM_BIP32_CHILD_DERIVE, &mechParams, sizeof(mechParams)};
CK_RV rv = C_DeriveKey(hSession, &mechanism, hMasterPrivKey, NULL, 0, NULL);
// fail if rv != CKR_OK
CK_OBJECT_HANDLE pubKey = mechanism.hPublicKey;
CK_OBJECT_HANDLE privKey = mechanism.hPrivateKey;
확장 공개 키 가져오기
확장 공개 키를 가져오는 샘플 코드는 다음과 같습니다. 가져오기가 완료되면 새로 생성된 키의 핸들이 pubKey
에 저장됩니다.
확장 공개 키 내보내기
확장 공개 키를 내보내는 샘플 코드는 다음과 같습니다. 내보내기가 완료되면 인코딩 된 키가 encodedKey
(BIP32 직렬화 형식)에 저장됩니다.
확장 개인 키 가져오기
확장 개인 키를 가져오는 샘플 코드는 다음과 같습니다. 키의 언랩핑 후 인코딩 된 키의 BIP32 직렬화 형식이 디코딩 됩니다.(템플릿 키 유형은 BIP32에 대해 확인됨) 가져오기가 완료되면 언랩핑 된 키의 핸들이 hUnwrappedKey
에 저장됩니다.
확장 개인 키 내보내기
확장 개인 키를 내보내는 샘플 코드는 다음과 같습니다. 키 랩핑 전에 C_WrapKey()
는 BIP32 키를 BIP32 직렬화 형식으로 변환시켜야 합니다. 내보내기가 완료되면 직렬화된 키가 key
에 저장됩니다.
PKCS#11 명세
암호화 표준인 PKCS#11의 명세는 다음과 같습니다.