Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Azure Cloud HSM ger robust stöd för certifikatlagring med hjälp av API:et PKCS#11. Den här artikeln beskriver hur du använder PKCS#11 API för att hantera X.509-certifikat, inklusive att skapa, kopiera, ta bort och hämta certifikatattribut. En detaljerad översikt över konfigurationen av certifikatlagring, inklusive krav och konfiguration, finns i Azure Cloud HSM-certifikatlagring.
Använda PKCS#11 API för X.509-certifikatlagring
Följande befintliga API:er i PKCS#11 för Azure Cloud HSM har utökats för att lägga till stöd för X.509 Public Key Certificates.
- C_CreateObject: Skapar ett nytt certifikatobjekt.
- C_DestroyObject: Tar bort ett befintligt certifikatobjekt.
- C_CopyObject: Kopierar ett befintligt certifikatobjekt.
- C_GetAttributeValue: Hämtar värdet för ett eller flera attribut för ett certifikatobjekt.
- C_SetAttributeValue: Uppdaterar värdet för ett eller flera attribut för ett certifikatobjekt.
- C_FindObjectsInit: Startar en sökning efter certifikatobjekt.
- C_FindObjects: Fortsätter sökningen efter certifikatobjekt.
- C_FindObjectsFinal: Avslutar en sökning efter certifikatobjekt.
C_CreateObject
C_CREATEOBJECT-API:et fungerar på samma sätt för både nycklar och certifikat. Den förväntar sig en matris med attribut, antalet attribut och en pekare till ett objekthandtag där det genererade handtaget lagras.
Nedan visas ett exempel på hur du använder 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;
}
Följande attribut representerar den minsta obligatoriska uppsättningen för att skapa ett X.509-certifikat i PKCS#11.
| Skikt | Egenskap | Datatyp | Beskrivning |
|---|---|---|---|
| Vanliga attribut | CKA_CLASS | CK_OBJEKT_KLASS | Objektklass (typ) |
| Certifikatobjekt | CKA_CERTIFICATE_TYPE | CK_CERTIFICATE_TYPE | Typ av certifikat, CKC_X_509 för X.509-certifikat för offentlig nyckel |
| X.509 Certifikatobjekt för offentlig nyckel | CKA_SUBJEKT | Bytematris | DER-kodning av certifikatets ämnesnamn |
| X.509 Certifikatobjekt för offentlig nyckel | CKA_VALUE | Bytematris | BER-kodning av certifikatet |
Följande attribut gäller för X.509-certifikat för offentlig nyckel.
| Skikt | Egenskap | Datatyp | Beskrivning |
|---|---|---|---|
| Vanliga attribut | CKA_CLASS | CK_OBJEKT_KLASS | Objektklass (typ) |
| Lagringsobjekt | CKA_TOKEN | CK_BBOOL | CK_TRUE om objektet är ett tokenobjekt. CK_FALSE om objektet är ett sessionsobjekt. Standardvärdet är CK_FALSE. |
| Lagringsobjekt | CKA_PRIVATE | CK_BBOOL | CK_TRUE om objektet är ett privat objekt. CK_FALSE om objektet är ett offentligt objekt. Standardvärdet är tokenspecifikt och kan bero på värdena för andra attribut i objektet. |
| Lagringsobjekt | CKA_MODIFIABLE | CK_BBOOL | CK_TRUE om objektet kan ändras; standard är CK_TRUE. |
| Lagringsobjekt | CKA_LABEL | RFC2279 sträng | Beskrivning av objektet (standard tom). |
| Lagringsobjekt | CKA_COPYABLE | CK_BBOOL | CK_TRUE om objektet kan kopieras med hjälp av C_CopyObject. Standardinställningen är CK_TRUE. Det kan inte ställas in på SANT när det en gång har ställts in på FALSKT. |
| Lagringsobjekt | CKA_DESTROYABLE | CK_BBOOL | CK_TRUE om objektet kan förstöras med hjälp av C_DestroyObject. Standardvärdet är CK_TRUE. |
| Certifikatobjekt | CKA_CERTIFICATE_TYPE | CK_CERTIFICATE_TYPE | Typ av certifikat, CKC_X_509 för X.509-certifikat för offentlig nyckel |
| Certifikatobjekt | CKA_TRUSTED | CK_BBOOL | Certifikatet kan litas på för den applikation det skapades för. |
| Certifikatobjekt | KKA_CERTIFIKAT_KATEGORI | KKA_CERTIFIKAT_KATEGORI | (standard CK_CERTIFICATE_CATEGORY_UNSPECIFIED) |
| Certifikatobjekt | CKA_CHECK_VALUE | Bytematris | Kontrollsumma |
| Certifikatobjekt | CKA_START_DATE | CK_DATE | Startdatum för certifikatet (standard tom) |
| Certifikatobjekt | CKA_SLUTDATUM | CK_DATE | Slutdatum för certifikatet (standard tom) |
| Certifikatobjekt | CKA_PUBLIC_KEY_INFO | Bytematris | DER-kodning av SubjectPublicKeyInfo för den offentliga nyckeln som finns i det här certifikatet (standard tom) |
| X.509 Certifikatobjekt för offentlig nyckel | CKA_SUBJEKT | Bytematris | DER-kodning av certifikatets ämnesnamn |
| X.509 Certifikatobjekt för offentlig nyckel | CKA_ID | Bytematris | Nyckelidentifierare för offentligt/privat nyckelpar (standard tom) |
| X.509 Certifikatobjekt för offentlig nyckel | CKA_ISSUER | Bytematris | DER-kodning av certifikatutfärdarens namn (standard tom) |
| X.509 Certifikatobjekt för offentlig nyckel | CKA_SERIAL_NUMBER | Bytematris | DER-kodning av certifikatserienumret (standard tom) |
| X.509 Certifikatobjekt för offentlig nyckel | CKA_VALUE | Bytematris | BER-kodning av certifikatet |
| X.509 Certifikatobjekt för offentlig nyckel | CKA_URL | RFC2279 sträng | Om det inte är tomt ger det här attributet url:en där det fullständiga certifikatet kan hämtas (standard tom) |
| X.509 Certifikatobjekt för offentlig nyckel | CKA_HASH_OF_SUBJECT_PUBLIC_KEY | Bytematris | Hash för subjektets offentliga nyckel (som standard tom). Hash-algoritmen definieras av CKA_NAME_HASH_ALGORITHM |
| X.509 Certifikatobjekt för offentlig nyckel | CKA_HASH_OF_ISSUER_PUBLIC_KEY | Bytematris | Hash för utfärdarens offentliga nyckel (standard tom). Hash-algoritmen definieras av CKA_NAME_HASH_ALGORITHM |
| X.509 Certifikatobjekt för offentlig nyckel | CKA_JAVA_MIDP_SECURITY_DOMAIN | CK_JAVA_MIDP_SECURITY_DOMAIN | Java MIDP-säkerhetsdomän. (förval CK_SECURITY_DOMAIN_UNSPECIFIED) |
| X.509 Certifikatobjekt för offentlig nyckel | CKA_NAME_HASH_ALGORITHM | CK_MECHANISM_TYPE | Definierar den mekanism som används för att beräkna CKA_HASH_OF_SUBJECT_PUBLIC_KEY och CKA_HASH_OF_ISSUER_PUBLIC_KEY. Om attributet inte finns är typen SHA-1 som standard. |
C_DestroyObject
C_DestroyObject-API:et tar ett sessionshandtag och objekthandtaget som är associerat med certifikatet som du vill ta bort. Om du anropar den här funktionen tas det angivna certifikatet bort från Azure Blob Storage-kontot genom att motsvarande JWS-blob med namnet pkcs11_certificate_<cert-handle>tas bort.
Nedan visas ett kodfragment som visar hur du anropar C_DestroyObject för certifikat (samma metod gäller för nycklar).
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
C_COPYOBJECT-API:et tar ett sessionshandtag, handtaget för det objekt som ska kopieras och en pekare för att ta emot handtaget för det nyligen skapade objektet. För att upprätthålla paritet med C_CopyObject implementeringen för nyckelobjekt i Azure Cloud HSM stöder certifikatimplementeringen inte att ändra attribut under kopieringsåtgärden.
Nedan visas ett exempelfragment som visar hur du använder C_CopyObject för att lagra certifikat.
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
API:et C_GetAttributeValue tillåter hämtning av alla attribut som anges i avsnittet C_CreateObject API. Det här API:et anropas vanligtvis två gånger. Det första anropet avgör storleken på attribut med okända längder, till exempel CKA_SUBJECT, som innehåller det DER-kodade certifikatämnet.
Nedan visas ett exempel på hur du anropar C_GetAttributeValue för att hämta storlekarna för de angivna attributen.
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
C_SetAttributeValue-API:et stöder nu uppdatering av certifikatobjekt. Det kräver att sessionshandtaget, certifikatets handtag uppdateras, en matris med attribut och deras nya värden samt antalet attribut som ska uppdateras. Endast attribut som anges i tabellen C_CreateObject API-användning stöds för uppdateringar. Försök att ändra attribut som inte stöds resulterar i ett misslyckat API-anrop.
Nedan visas ett kodfragment som visar hur C_SetAttributeValue kan användas med certifikatobjekt.
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
API:et C_FindObjects* har nu stöd för att hitta certifikatobjekt utöver nyckelobjekt. En sökåtgärd kan returnera både nyckel- och certifikathandtag om sökmallen innehåller attribut som är gemensamma för båda objekttyperna. API:et C_FindObjectsInit har förbättrats för att stödja alla certifikatrelaterade attribut som anges i tabellen C_CreateObject API-användning.
Nedan visas ett exempel på ett C_FindObjectsInit-anrop som utför en certifikatsökning med hjälp av attributen CKA_CLASS, CKA_CERTIFICATE_TYPE och CKA_LABEL för att hitta alla matchande certifikatobjekt.
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
När du har initierat sökparametrarna används C_FindObjects-API:et för att hämta matchande objekthandtag. Den returnerar också antalet objekt som hittades. Det här API:et tar sessionshandtaget, en matris för att lagra de resulterande objekthandtagen, det maximala antalet objekt som ska hämtas och en utdataparameter som anger hur många objekt som hittades.
Kodfragmentet nedan visar ett anrop till C_FindObjects efter konfigurationen av sökmallen i C_FindObjectsInit exemplet ovan.
// 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
C_FINDOBJECTSFINAL-API:et fungerar på samma sätt för både nyckel- och certifikatobjekt. Den tar den aktuella sessionsreferensen som ett argument och utför rensning av alla sökrelaterade strukturer och minne som allokerats under C_FindObjectsInit-anropet.
Nedan visas ett kodfragment som visar hur du anropar C_FindObjectsFinal för att slutföra och rensa sökprocessen som initieras av api:erna för C_FindObjectsInit och C_FindObjects.
// 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;
}
}
Konfigurera och köra PKCS#11-programmet med Azure Cloud HSM
Azure Cloud HSM innehåller exempelprogramkod som hjälper dig att verifiera certifikatlagring, som finns i Azure Cloud HSM Certificate Storage-integreringsguiden i Azure Cloud HSM SDK på GitHub.
Certifikatstruktur i datalagring
Verifiera certifikat i lagring
Efter ett lyckat anrop till API:et C_CreateObject() visas det nyligen skapade certifikatobjektet i ditt Azure Blob Storage-konto enligt azcloudhsm_application.cfg-filen. Bloben namnges med formatet pkcs11_certificate_<object-handle>, enligt nedan. Certifikatobjekt tilldelas objektreferenser från 0xFFF00000 till 0xFFFFFFFF (decimalintervall: 4 293 918 720 till 4 294 967 295), vilket ger stöd för upp till 1 048 575 certifikat.
Från både Azure-portalen och från den virtuella Azure-datorn kan du se de certifikat som lagras.
Verifiera från Azure-portalen
Verifiera från en virtuell Azure-dator med AZ CLI installerat
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
Om du laddar ned bloben eller visar den i Azure-portalen och kontrollerar dess innehåll visas att certifikatet lagras som en JWS-token (JSON-webbsignatur). Token följer JWS-standardstrukturen, som är uppdelad i följande format:
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)
Nästa steg
- Självstudie om Azure Cloud HSM-certifikatlagring: Lär dig hur du konfigurerar krav för certifikatlagring och konfigurerar Azure Blob Storage för PKCS#11-program.
- Översikt över Azure Cloud HSM
- Skydda din Azure Cloud HSM