샘플 코드
    • PDF

    샘플 코드

    • PDF

    기사 요약

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

    키를 생성하거나 가져오고 내보낼 때 사용되는 샘플 코드를 설명합니다.

    참고

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

    마스터 키 페어 파생

    권한이 없는 사용자가 체인 코드를 볼 수 없도록 마스터 공개 및 개인 키의 CKA_PRIVATETRUE로 설정해 주십시오. 마스터 키는 키 파생 시에만 사용해야 합니다. 템플릿에 속성이 없는 경우 공개/개인 키의 버전 바이트 기본값은 0x0488B21E/0x0488ADE4이며, 이는 메인 비트코인 네트워크의 키에 대한 BIP32에 명시된 값입니다.

    마스터 키 페어를 파생하는 샘플 코드는 다음과 같습니다. 파생이 완료되면 새로운 키 핸들이 pubKeyprivKey에 저장됩니다.

    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_PRIVATETRUE로 설정해 주십시오. 하위 리프 키(키 트리 최하단에 위치한 키)는 파생에 사용할 수 없으며 서명, 확인, 암호화 및 복호화에 사용해야 합니다. 부모 자식 키를 사용하려면 파생 속성을 설정해야 합니다. 템플릿에 속성이 없는 경우 공개/개인 키의 버전 바이트 기본값은 0x0488B21E/0x0488ADE4이며, 이는 메인 비트코인 네트워크의 키에 대한 BIP32에 명시된 값입니다.

    하위 리프 키를 파생하는 샘플 코드는 다음과 같습니다. 파생이 완료되면 새로운 키 핸들이 pubKeyprivKey에 저장됩니다. 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에 저장됩니다.

    CK_ATTRIBUTE template[] =
    {
       {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_CHAR_PTR encodedKey = “xpub661MyMwAqRbcFtXgS5…”; //BIP32 serialization format
    CK_OBJECT_HANDLE pubKey;
    
    CK_RV rv = CA_Bip32ImportKey(hSession, template, ARRAY_SIZE(template), encodedKey, &pubKey);
    

    확장 공개 키 내보내기

    확장 공개 키를 내보내는 샘플 코드는 다음과 같습니다. 내보내기가 완료되면 인코딩 된 키가 encodedKey(BIP32 직렬화 형식)에 저장됩니다.

    CK_CHAR encodedKey[CKG_BIP32_MAX_SERIALIZED_LEN+1];
    CK_ULONG ulEncodedKeySize = sizeof(encodedKey); 
    
    CK_RV rv = CA_Bip32ExportPubKey(hSession, hObject, encodedKey, &ulEncodedKeySize );
    

    확장 개인 키 가져오기

    확장 개인 키를 가져오는 샘플 코드는 다음과 같습니다. 키의 언랩핑 후 인코딩 된 키의 BIP32 직렬화 형식이 디코딩 됩니다.(템플릿 키 유형은 BIP32에 대해 확인됨) 가져오기가 완료되면 언랩핑 된 키의 핸들이 hUnwrappedKey에 저장됩니다.

    CK_ATTRIBUTE template[] =
    {
       {CKA_CLASS              &keyClass,    sizeof(keyClass)},
       {CKA_TOKEN,             &bToken,      sizeof(bToken)},
       {CKA_KEY_TYPE           &keyType,     sizeof(keyType)},
       {CKA_PRIVATE,           &bTrue,       sizeof(bTrue)},
       {CKA_DERIVE,            &bTrue,       sizeof(bTrue)},
       {CKA_MODIFIABLE,        &bTrue,       sizeof(bTrue)},
       {CKA_LABEL,             pbLabel,      strlen(pbLabel)},
       {CKA_SENSITIVE          &bTrue,       sizeof(bTrue)},
    };
    
    CK_CHAR_PTR encodedKey = “xprv9s21ZrQH143K3QTDL4LXw2F…”; 
    CK_MECHANISM mechanism = {CKM_AES_KWP, NULL, 0};
    CK_BYTE wrappedKey[256];
    CK_ULONG wrappedKeyLen = sizeof(wrappedKey);
    CK_OBJECT_HANDLE hUnwrappedKey;
    
    CK_RV rv = C_EncryptInit(hSession, &mechanism, hWrappingKey);
    // fail if rv != CKR_OK
    
    rv = C_Encrypt(hSession, encodedKey, sizeof(encodedKey), wrappedKey, &wrappedKeyLen);
    // fail if rv != CKR_OK
    
    rv = C_UnwrapKey(hSession, &mechanism, hWrappingKey, wrappedKey, wrappedKeyLen, template, ARRAY_SIZE(template), &hUnwrappedKey); 
    

    확장 개인 키 내보내기

    확장 개인 키를 내보내는 샘플 코드는 다음과 같습니다. 키 랩핑 전에 C_WrapKey()는 BIP32 키를 BIP32 직렬화 형식으로 변환시켜야 합니다. 내보내기가 완료되면 직렬화된 키가 key에 저장됩니다.

    CK_MECHANISM mechanism = {CKM_AES_KWP, NULL, 0};
    CK_BYTE key[256];
    CK_ULONG keyLen = sizeof(key);
    
    CK_RV rv = C_WrapKey(hSession, &mechanism, hWrappingKey, hKeyToWrap, key, &keyLen);
    // fail if rv != CKR_OK
    
    rv = C_DecryptInit(hSession, &mechanism, hWrappingKey);
    // fail if rv != CKR_OK
    
    rv = C_Decrypt(hSession, key, keyLen, key, &keyLen);
    // fail if rv != CKR_OK
    
    key[keyLen] = 0 // The key isn’t NULL terminated after C_Decrypt().
    

    PKCS#11 명세

    암호화 표준인 PKCS#11의 명세는 다음과 같습니다.

    #define CKK_BIP32 (CKK_VENDOR_DEFINED  | 0x14)
    #define CKM_BIP32_MASTER_DERIVE (CKM_VENDOR_DEFINED | 0xE00)
    #define CKM_BIP32_CHILD_DERIVE (CKM_VENDOR_DEFINED |  0xE01)
    #define CKR_BIP32_CHILD_INDEX_INVALID (CKR_VENDOR_DEFINED |         0x83)
    #define CKR_BIP32_INVALID_HARDENED_DERIVATION (CKR_VENDOR_DEFINED | 0x84)
    #define CKR_BIP32_MASTER_SEED_LEN_INVALID (CKR_VENDOR_DEFINED |     0x85)
    #define CKR_BIP32_MASTER_SEED_INVALID (CKR_VENDOR_DEFINED |         0x86)
    #define CKR_BIP32_INVALID_KEY_PATH_LEN (CKR_VENDOR_DEFINED |        0x87)
    #define CKA_BIP32_CHAIN_CODE (CKA_VENDOR_DEFINED |         0x1100)
    #define CKA_BIP32_VERSION_BYTES (CKA_VENDOR_DEFINED |      0x1101)
    #define CKA_BIP32_CHILD_INDEX (CKA_VENDOR_DEFINED |        0x1102)
    #define CKA_BIP32_CHILD_DEPTH (CKA_VENDOR_DEFINED |        0x1103)
    #define CKA_BIP32_ID (CKA_VENDOR_DEFINED |                 0x1104)
    #define CKA_BIP32_FINGERPRINT (CKA_VENDOR_DEFINED |        0x1105)
    #define CKA_BIP32_PARENT_FINGERPRINT (CKA_VENDOR_DEFINED | 0x1106)
    #define CKG_BIP32_VERSION_MAINNET_PUB   (0x0488B21E)
    #define CKG_BIP32_VERSION_MAINNET_PRIV  (0x0488ADE4)
    #define CKG_BIP32_VERSION_TESTNET_PUB   (0x043587CF)
    #define CKG_BIP32_VERSION_TESTNET_PRIV  (0x04358394)
    #define CKG_BIP44_PURPOSE               (0x0000002C)
    #define CKG_BIP44_COIN_TYPE_BTC         (0x00000000)
    #define CKG_BIP44_COIN_TYPE_BTC_TESTNET (0x00000001)
    #define CKG_BIP32_EXTERNAL_CHAIN        (0x00000000)
    #define CKG_BIP32_INTERNAL_CHAIN        (0x00000001)
    #define CKG_BIP32_MAX_SERIALIZED_LEN    (112)
    #define CKF_BIP32_HARDENED              (0x80000000)
    #define CKF_BIP32_MAX_PATH_LEN          (255)
    

    이 문서가 도움이 되었습니까?

    What's Next
    Changing your password will log you out immediately. Use the new password to log back in.
    First name must have atleast 2 characters. Numbers and special characters are not allowed.
    Last name must have atleast 1 characters. Numbers and special characters are not allowed.
    Enter a valid email
    Enter a valid password
    Your profile has been successfully updated.