Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Azure Cloud HSM biedt robuuste ondersteuning voor certificaatopslag met behulp van de PKCS#11-API. In dit artikel wordt uitgelegd hoe u de PKCS#11-API gebruikt om X.509-certificaten te beheren, waaronder het maken, kopiëren, verwijderen en ophalen van certificaatkenmerken. Zie Azure Cloud HSM-certificaatopslag voor een gedetailleerd overzicht van de installatie van certificaatopslag, inclusief vereisten en configuratie.
PKCS#11 API gebruiken voor X.509-certificaatopslag
De volgende bestaande API's in PKCS#11 voor Azure Cloud HSM zijn uitgebreid om ondersteuning toe te voegen voor X.509-certificaten voor openbare sleutel.
- C_CreateObject: Hiermee maakt u een nieuw certificaatobject.
- C_DestroyObject: Hiermee verwijdert u een bestaand certificaatobject.
- C_CopyObject: Hiermee kopieert u een bestaand certificaatobject.
- C_GetAttributeValue: haalt de waarde op van een of meer kenmerken van een certificaatobject.
- C_SetAttributeValue: werkt de waarde van een of meer kenmerken van een certificaatobject bij.
- C_FindObjectsInit: Hiermee start u een zoekopdracht naar certificaatobjecten.
- C_FindObjects: hiermee wordt een zoekopdracht voortgezet naar certificaatobjecten.
- C_FindObjectsFinal: Hiermee wordt een zoekopdracht naar certificaatobjecten beëindigd.
C_CreateObject
De C_CreateObject API-functies op dezelfde manier voor zowel sleutels als certificaten. Er wordt een matrix met kenmerken, het aantal kenmerken en een aanwijzer naar een objectgreep verwacht waarin de gegenereerde ingang wordt opgeslagen.
Hieronder ziet u een voorbeeld van het gebruik van de C_CreateObject.
int create_cert(CK_SESSION_HANDLE session_rw, CK_OBJECT_HANDLE_PTR cert_handle)
{
// Dummy certificate data
CK_BYTE certData[] = { 0x30, 0x82, 0x03, 0x08, 0x30, 0x82, 0x02, 0xD0 }; // Sample DER-encoded cert
CK_ULONG certSize = sizeof(certData);
CK_OBJECT_CLASS objClass = CKO_CERTIFICATE;
CK_CERTIFICATE_TYPE certType = CKC_X_509;
CK_BBOOL trueValue = CK_TRUE;
CK_BYTE id[] = {123};
// Dummy DER-encoded Subject Name (adjust as needed)
CK_BYTE subjectData[] = { 0x30, 0x1D, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03,
0x55, 0x04, 0x03, 0x0C, 0x12, 'M', 'y', 'C', 'e',
'r', 't', 'i', 'f', 'i', 'c', 'a', 't', 'e', '-', 'B', 'b', 'j' };
CK_ULONG subjectSize = sizeof(subjectData);
CK_ATTRIBUTE certTemplate[] = {
{ CKA_CLASS, &objClass, sizeof(objClass) },
{ CKA_CERTIFICATE_TYPE, &certType, sizeof(certType) },
{ CKA_TOKEN, &trueValue, sizeof(trueValue) },
{ CKA_LABEL, "MyCertificate", 13 },
{ CKA_SUBJECT, subjectData, subjectSize },
{ CKA_ID, id, sizeof(id) },
{ CKA_VALUE, certData, certSize }
};
int n_attr = sizeof(certTemplate) / sizeof(CK_ATTRIBUTE);
if ((func_list->C_CreateObject)(session_rw, certTemplate,
n_attr, cert_handle)) {
return FAILED;
}
#ifdef DEBUG
printf("The cert handle created is : %lu \n", *cert_handle);
#endif
return CKR_OK;
}
De volgende kenmerken vertegenwoordigen de minimaal vereiste set voor het maken van een X.509-certificaat in PKCS#11.
| Laag | Eigenschap | Gegevenssoort | Beschrijving |
|---|---|---|---|
| Algemene kenmerken | CKA_CLASS | CK_OBJECT_CLASS | Objectklasse (type) |
| Certificaatobjecten | CKA_CERTIFICATE_TYPE | CK_CERTIFICATE_TYPE | Type certificaat, CKC_X_509 voor X.509-certificaten met openbare sleutel |
| X.509 Openbare Sleutelcertificaatobjecten | CKA_SUBJECT | Bytematrix | DER-codering van de onderwerpnaam van het certificaat |
| X.509 Openbare Sleutelcertificaatobjecten | CKA_VALUE | Bytematrix | BER-codering van het certificaat |
De volgende kenmerken zijn van toepassing op X.509-certificaten voor openbare sleutels.
| Laag | Eigenschap | Gegevenssoort | Beschrijving |
|---|---|---|---|
| Algemene kenmerken | CKA_CLASS | CK_OBJECT_CLASS | Objectklasse (type) |
| Opslagobjecten | CKA_TOKEN | CK_BBOOL | CK_TRUE als object een tokenobject is; CK_FALSE als het object een sessieobject is. De standaardwaarde is CK_FALSE. |
| Opslagobjecten | CKA_PRIVATE | CK_BBOOL | CK_TRUE als het object een privéobject is; CK_FALSE als het object een openbaar object is. De standaardwaarde is tokenspecifiek en kan afhankelijk zijn van de waarden van andere kenmerken van het object. |
| Opslagobjecten | CKA_MODIFIABLE | CK_BBOOL | CK_TRUE als het object kan worden gewijzigd, wordt de standaardwaarde CK_TRUE. |
| Opslagobjecten | CKA_LABEL | RFC2279 tekenreeks | Beschrijving van het object (standaard leeg). |
| Opslagobjecten | CKA_COPYABLE | CK_BBOOL | CK_TRUE als het object kan worden gekopieerd met behulp van C_CopyObject. De standaardinstelling is CK_TRUE. Kan niet worden ingesteld op TRUE zodra deze is ingesteld op ONWAAR. |
| Opslagobjecten | CKA_DESTROYABLE | CK_BBOOL | CK_TRUE als het object kan worden vernietigd met behulp van C_DestroyObject. De standaardwaarde is CK_TRUE. |
| Certificaatobjecten | CKA_CERTIFICATE_TYPE | CK_CERTIFICATE_TYPE | Type certificaat, CKC_X_509 voor X.509-certificaten met openbare sleutel |
| Certificaatobjecten | CKA_TRUSTED | CK_BBOOL | Het certificaat kan worden vertrouwd voor de toepassing waarvoor het is gemaakt. |
| Certificaatobjecten | CKA_CERTIFICATE_CATEGORY | CKA_CERTIFICATE_CATEGORY | (standaard CK_CERTIFICATE_CATEGORY_UNSPECIFIED) |
| Certificaatobjecten | CKA_CHECK_VALUE | Bytematrix | Checksum |
| Certificaatobjecten | CKA_STARTDATUM | CK_DATE | Begindatum voor het certificaat (standaard leeg) |
| Certificaatobjecten | CKA_EINDDATUM | CK_DATE | Einddatum voor het certificaat (standaard leeg) |
| Certificaatobjecten | CKA_PUBLIC_KEY_INFO | Byte-array | DER-codering van subjectPublicKeyInfo voor de openbare sleutel in dit certificaat (standaard leeg) |
| X.509 Openbare Sleutelcertificaatobjecten | CKA_SUBJECT | Bytematrix | DER-codering van de onderwerpnaam van het certificaat |
| X.509 Openbare Sleutelcertificaatobjecten | CKA_ID | Bytematrix | Sleutel-id voor openbaar/persoonlijk sleutelpaar (standaard leeg) |
| X.509 Openbare Sleutelcertificaatobjecten | CKA_ISSUER | Bytematrix | DER-codering van de naam van de certificaatverlener (standaard leeg) |
| X.509 Openbare Sleutelcertificaatobjecten | CKA_SERIAL_NUMBER | Bytematrix | DER-codering van het serienummer van het certificaat (standaard leeg) |
| X.509 Openbare Sleutelcertificaatobjecten | CKA_VALUE | Bytematrix | BER-codering van het certificaat |
| X.509 Openbare Sleutelcertificaatobjecten | CKA_URL | RFC2279 tekenreeks | Als dit kenmerk niet leeg is, krijgt u de URL waar het volledige certificaat kan worden verkregen (standaard leeg) |
| X.509 Openbare Sleutelcertificaatobjecten | CKA_HASH_OF_SUBJECT_PUBLIC_KEY | Bytematrix | Hash van de openbare sleutel van het onderwerp (standaard leeg). Hash-algoritme wordt gedefinieerd door CKA_NAME_HASH_ALGORITHM |
| X.509 Openbare Sleutelcertificaatobjecten | CKA_HASH_OF_ISSUER_PUBLIC_KEY | Bytematrix | Hash van de openbare sleutel van de verlener (standaard leeg). Hash-algoritme wordt gedefinieerd door CKA_NAME_HASH_ALGORITHM |
| X.509 Openbare Sleutelcertificaatobjecten | CKA_JAVA_MIDP_SECURITY_DOMAIN | CK_JAVA_MIDP_SECURITY_DOMAIN | Java MIDP-beveiligingsdomein. (standaard CK_SECURITY_DOMAIN_ONBEPAALD) |
| X.509 Openbare Sleutelcertificaatobjecten | CKA_NAME_HASH_ALGORITHM | CK_MECHANISM_TYPE | Definieert het mechanisme dat wordt gebruikt om CKA_HASH_OF_SUBJECT_PUBLIC_KEY en CKA_HASH_OF_ISSUER_PUBLIC_KEY te berekenen. Als het kenmerk niet aanwezig is, wordt het type standaard ingesteld op SHA-1. |
C_DestroyObject
De C_DestroyObject-API gebruikt een sessiehandgreep en de objectgreep die is gekoppeld aan het certificaat dat u wilt verwijderen. Als u deze functie aanroept, wordt het opgegeven certificaat verwijderd uit het Azure Blob Storage-account door de bijbehorende JWS-blob met de naam pkcs11_certificate_<cert-handle>te verwijderen.
Hieronder ziet u een codefragment waarin wordt gedemonstreerd hoe u C_DestroyObject aanroept voor certificaten (dezelfde benadering is van toepassing op sleutels).
int delete_cert(CK_SESSION_HANDLE session_rw, CK_OBJECT_HANDLE cert_handle)
{
CK_RV rv = 0;
rv = (func_list->C_DestroyObject)(session_rw, cert_handle);
if(rv != CKR_OK) {
printf("Deleting Certificate failed \n");
return rv;
}
return rv;
}
C_CopyObject
De C_CopyObject-API gebruikt een sessiehandgreep, de ingang van het object dat moet worden gekopieerd en een aanwijzer om de ingang van het zojuist gemaakte object te ontvangen. Om pariteit te behouden met de C_CopyObject-implementatie voor sleutelobjecten in Azure Cloud HSM, biedt de certificaatimplementatie geen ondersteuning voor het wijzigen van kenmerken tijdens de kopieerbewerking.
Hieronder ziet u een voorbeeldfragment waarin wordt gedemonstreerd hoe u C_CopyObject gebruikt voor het opslaan van certificaten.
int copy_cert(CK_SESSION_HANDLE session_rw, CK_OBJECT_HANDLE cert_handle,
CK_OBJECT_HANDLE_PTR copied_cert_handle)
{
CK_RV rv = 0;
rv = (func_list->C_CopyObject)(session_rw, cert_handle, NULL, 0, copied_cert_handle);
if(rv != CKR_OK) {
printf("Copying Certificate failed \n");
return rv;
}
return rv;
}
C_GetAttributeValue
Met de C_GetAttributeValue-API kunnen alle kenmerken worden opgehaald die worden vermeld in de sectie C_CreateObject API. Deze API wordt doorgaans twee keer aangeroepen. De eerste aanroep bepaalt de grootte van kenmerken met onbekende lengten, zoals CKA_SUBJECT, die het onderwerp van het DER-gecodeerde certificaat bevat.
Hieronder ziet u een voorbeeld van het aanroepen van C_GetAttributeValue om de grootten van de opgegeven kenmerken te verkrijgen.
int get_cert_attribute(CK_SESSION_HANDLE session_rw, CK_OBJECT_HANDLE_PTR cert_handle)
{
CK_RV rv = 0;
CK_ULONG cka_class = 0;
CK_CERTIFICATE_TYPE cka_cert_type = 0;
CK_BBOOL cka_token = 0;
char* cka_label = NULL;
char* cka_subject = NULL;
CK_BYTE* cka_id = NULL;
CK_BYTE* cka_value = NULL;
// Determine size needed for each attribute by calling C_GetAttributeValue with NULL pointers
// and zero as the length.
CK_ATTRIBUTE cert_template[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_CERTIFICATE_TYPE, NULL, 0 },
{ CKA_TOKEN, NULL, 0 },
{ CKA_LABEL, NULL, 0 },
{ CKA_ID, NULL, 0 },
};
int n_attr = sizeof(cert_template) / sizeof(CK_ATTRIBUTE);
rv = (func_list->C_GetAttributeValue)(session_rw, *cert_handle, cert_template, n_attr);
if (rv != CKR_OK) {
printf("C_GetAttributeValue failed with %ld\n", rv);
return FAILED;
}
Once the attribute sizes are known, memory can be allocated accordingly. A second call to the C_GetAttributeValue API is then made to retrieve the attribute values and store them in the allocated memory.
The image below shows a code snippet demonstrating this process based on the previous example:
cka_label = (char*)malloc(cert_template[3].ulValueLen);
if (cka_label == NULL) {
printf("Memory allocation failed for CKA_LABEL.\n");
rv = FAILED;
goto end_test_get_cert_attribute;
}
cert_template[3].pValue = cka_label;
if (cert_template[4].ulValueLen <= 0) {
printf("CKA_ID size must be > 0.\n");
rv = FAILED;
goto end_test_get_cert_attribute;
}
cka_id = (CK_BYTE*)malloc(cert_template[4].ulValueLen);
if (cka_id == NULL) {
printf("Memory allocation failed for CKA_ID.\n");
rv = FAILED;
goto end_test_get_cert_attribute;
}
cert_template[4].pValue = cka_id;
rv = (func_list->C_GetAttributeValue)(session_rw, *cert_handle, cert_template, n_attr);
if (rv != CKR_OK) {
printf("C_GetAttributeValue failed with %ld\n", rv);
rv = FAILED;
goto end_test_get_cert_attribute;
}
C_SetAttributeValue
De C_SetAttributeValue-API ondersteunt nu het bijwerken van certificaatobjecten. Hiervoor zijn de sessie-handle, de handle van het certificaat dat moet worden bijgewerkt, een array met kenmerken en hun nieuwe waarden, en het aantal kenmerken dat moet worden bijgewerkt, vereist. Alleen kenmerken die worden vermeld in de tabel C_CreateObject API-gebruik, worden ondersteund voor updates. Als u niet-ondersteunde kenmerken probeert te wijzigen, treedt er een mislukte API-aanroep op.
Hieronder ziet u een fragment waarin wordt getoond hoe C_SetAttributeValue kan worden gebruikt met certificaatobjecten.
int set_cert_attribute(CK_SESSION_HANDLE session_rw, CK_OBJECT_HANDLE_PTR cert_handle)
{
CK_RV rv = CKR_OK;
CK_BBOOL falseValue = CK_FALSE;
CK_BYTE subjectData[] = { 0x40, 0x41, 0x42, 0x43, 0x44 };
CK_BYTE id[] = {254};
CK_BYTE certData[] = { 0x10, 0x20, 0x30, 0x40, 0x50, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
CK_ATTRIBUTE certTemplateValid1[] = {
{ CKA_TOKEN, &falseValue, sizeof(falseValue) },
{ CKA_LABEL, "This is a new label", strlen("This is a new label") },
{ CKA_SUBJECT, subjectData, sizeof(subjectData) },
{ CKA_ID, id, sizeof(id) },
{ CKA_VALUE, certData, sizeof(certData) }
};
int n_attr = sizeof(certTemplateValid1) / sizeof(CK_ATTRIBUTE);
rv = (func_list->C_SetAttributeValue)(session_rw, *cert_handle, certTemplateValid1, n_attr);
if (rv != CKR_OK) {
printf("test_set_cert_attribute failed when updating attribute values.\n");
return FAILED;
}
return rv;
}
C_FindObjectsInit
De C_FindObjects* API biedt nu ondersteuning voor het zoeken van certificaatobjecten naast sleutelobjecten. Met een zoekbewerking kunnen zowel sleutel- als certificaatingangen worden geretourneerd als de zoeksjabloon kenmerken bevat die gebruikelijk zijn voor beide objecttypen. De C_FindObjectsInit-API is uitgebreid om alle certificaatgerelateerde kenmerken te ondersteunen die worden vermeld in de tabel C_CreateObject API-gebruik.
Hieronder ziet u een voorbeeld van een C_FindObjectsInit-aanroep waarmee een certificaatzoekopdracht wordt uitgevoerd met behulp van de kenmerken CKA_CLASS, CKA_CERTIFICATE_TYPE en CKA_LABEL om alle overeenkomende certificaatobjecten te vinden.
int find_cert(CK_SESSION_HANDLE session_rw, CK_OBJECT_HANDLE cert_handle)
{
CK_RV rv;
CK_OBJECT_CLASS objClass = CKO_CERTIFICATE;
CK_CERTIFICATE_TYPE certType = CKC_X_509;
CK_ATTRIBUTE certTemplate[] = {
{ CKA_CLASS, &objClass, sizeof(objClass) },
{ CKA_CERTIFICATE_TYPE, &certType, sizeof(certType) },
{ CKA_LABEL, "MyCertificate", 13 }
};
// Step 1: Initialize the search
rv = (func_list->C_FindObjectsInit)(session_rw, certTemplate, sizeof(certTemplate) / sizeof(CK_ATTRIBUTE));
if (rv != CKR_OK) {
printf("C_FindObjectsInit failed: 0x%lX\n", rv);
return rv;
}
C_FindObjects
Nadat de zoekparameters zijn geïnitialiseerd, wordt de C_FindObjects-API gebruikt om de overeenkomende objectgrepen op te halen. Het retourneert ook het aantal gevonden objecten. Deze API gebruikt de sessie-handle, een matrix voor het opslaan van de resulterende objectgrepen, het maximum aantal objecten dat moet worden opgehaald en een uitvoerparameter die aangeeft hoeveel objecten zijn gevonden.
In het onderstaande fragment ziet u een aanroep van C_FindObjects na de installatie van de zoeksjabloon in het bovenstaande C_FindObjectsInit voorbeeld.
// Step 2: Call C_FindObjects
CK_OBJECT_HANDLE_PTR foundObjects = NULL;
CK_ULONG maxObjects = 50;
foundObjects = (CK_OBJECT_HANDLE_PTR)malloc(sizeof(CK_OBJECT_HANDLE) * maxObjects);
if (!foundObjects) {
printf("Memory allocation failed\n");
return CKR_HOST_MEMORY;
}
CK_ULONG foundCount = 0;
rv = (func_list->C_FindObjects)(session_rw, foundObjects, maxObjects, &foundCount);
if (rv != CKR_OK) {
printf("C_FindObjects failed: 0x%lX\n", rv);
(func_list->C_FindObjectsFinal)(session_rw); // Ensure cleanup
free(foundObjects);
return rv;
}
C_FindObjectsFinal
De C_FindObjectsFinal-API gedraagt zich hetzelfde voor sleutel- en certificaatobjecten. Hierbij wordt de huidige sessiegreep als argument gebruikt en worden alle zoekgerelateerde structuren en het geheugen opgeschoond die tijdens de C_FindObjectsInit aanroep zijn toegewezen.
Hieronder ziet u een fragment waarin wordt getoond hoe u C_FindObjectsFinal aanroept om het zoekproces dat is gestart door de C_FindObjectsInit en C_FindObjects API's, te voltooien en op te schonen.
// Step 3: Finalize the search
rv = (func_list->C_FindObjectsFinal)(session_rw);
if (rv != CKR_OK) {
printf("C_FindObjectsFinal failed: 0x%lX\n", rv);
free(foundObjects);
return rv;
}
}
Uw PKCS#11-toepassing configureren en uitvoeren met Azure Cloud HSM
Azure Cloud HSM bevat voorbeeldtoepassingscode om certificaatopslag te valideren, die beschikbaar is in de Integratiehandleiding voor Azure Cloud HSM Certificate Storage in de Azure Cloud HSM SDK op GitHub.
Certificaatstructuur in opslag
Certificaten in opslag controleren
Na een geslaagde aanroep van de C_CreateObject() API wordt het zojuist gemaakte certificaatobject weergegeven in uw Azure Blob Storage-account, zoals opgegeven in het bestand azcloudhsm_application.cfg. De blob krijgt de naam met behulp van de indeling pkcs11_certificate_<object-handle>, zoals hieronder wordt weergegeven. Certificaatobjecten worden objectgrepen toegewezen, variërend van 0xFFF00000 tot 0xFFFFFFFF (decimaal bereik: 4.293.918.720 tot 4.294.967.295), waardoor maximaal 1.048.575 certificaten kunnen worden ondersteund.
Vanuit zowel Azure Portal als vanuit uw Azure-VM kunt u de certificaten zien die zijn opgeslagen.
Verifiëren vanuit De Azure-portal
Controleren vanaf azure-VM waarop AZ CLI is geïnstalleerd
chsmVMAdmin@AdminVM:~$ az login --identity
[
{
"environmentName": "AzureCloud",
"homeTenantId": "",
"id": "",
"isDefault": true,
"managedByTenants": [],
"name": "Test Subscription",
"state": "Enabled",
"tenantId": "",
"user": {
"assignedIdentityInfo": "MSI",
"name": "systemAssignedIdentity",
"type": "servicePrincipal"
}
}
]
chsmVMAdmin@AdminVM:~$ az storage blob list \
--account-name chsmstorage \
--container-name certificates \
--auth-mode login \
--output table
Name Blob Type Blob Tier Length Content Type Last Modified
----------------------------------- ----------- ----------- -------- ------------------------ -------------------------
pkcs11_certificate_4293918720 BlockBlob Hot 1305 application/octet-stream 2025-05-16T22:43:31+00:00
pkcs11_certificate_4293918721 BlockBlob Hot 1305 application/octet-stream 2025-05-16T22:47:25+00:00
pkcs11_certificate_4293918722 BlockBlob Hot 1305 application/octet-stream 2025-05-16T22:47:25+00:00
pkcs11_certificate_4293918723 BlockBlob Hot 3452 application/octet-stream 2025-05-16T22:56:28+00:00
Als u de blob downloadt of bekijkt in Azure Portal en de inhoud ervan inspecteert, ziet u dat het certificaat is opgeslagen als een JWS-token (JSON Web Signature). Het token volgt de standaard JWS-structuur, die is onderverdeeld in de volgende indeling:
chsmVMAdmin@AdminVM:~$ az storage blob list \
--account-name chsmstorage \
--container-name certificates \
--auth-mode login \
--output table
Name Blob Type Blob Tier Length Content Type Last Modified
----------------------------------- ----------- ----------- -------- ------------------------ -------------------------
pkcs11_certificate_4293918720 BlockBlob Hot 1305 application/octet-stream 2025-05-16T22:43:31+00:00
pkcs11_certificate_4293918721 BlockBlob Hot 1305 application/octet-stream 2025-05-16T22:47:25+00:00
pkcs11_certificate_4293918722 BlockBlob Hot 1305 application/octet-stream 2025-05-16T22:47:25+00:00
pkcs11_certificate_4293918723 BlockBlob Hot 3452 application/octet-stream 2025-05-16T22:56:28+00:00
chsmVMAdmin@AdminVM:~$ az storage blob download \
--account-name chsmstorage \
--container-name certificates \
--name pkcs11_certificate_4293918723 \
--file pkcs11_certificate_4293918723.crt \
--auth-mode login
Finished[########################################] 100.0000%
{
"container": "certificates",
"content": ""
}
chsmVMAdmin@AdminVM:~$ cat pkcs11_certificate_4293918723.crt
eyJhbgGciOiJSUzUxMiIsImp... (base64-encoded certificate continues)
Volgende stappen
- Zelfstudie voor Azure Cloud HSM Certificate Storage: Meer informatie over het instellen van vereisten voor certificaatopslag en het configureren van Azure Blob Storage voor PKCS#11-toepassingen.
- Overzicht van Azure Cloud HSM
- Uw Azure Cloud HSM beveiligen