Potvrzení o transakcích zápisu důvěrných registrů Azure
K vynucení záruk integrity transakcí používá Azure Confidential Ledger datovou strukturu merkle stromové struktury k zaznamenání hodnoty hash všech bloků transakcí, které jsou připojeny k neměnné registru. Po potvrzení transakce zápisu můžou uživatelé důvěrného registru Azure získat kryptografický důkaz Merkle nebo potvrzení o položce vytvořené v důvěrném registru, aby ověřili, že operace zápisu byla správně uložena. Potvrzení o zápisu transakce je důkaz, že systém potvrdil odpovídající transakci a lze jej použít k ověření, že položka byla účinně připojena k registru.
Další podrobnosti o tom, jak se Merkle Tree používá v důvěrném registru, najdete v dokumentaci CCF.
Získání potvrzení o transakcích zápisu
Nastavení a požadavky
Uživatelé důvěrného registru Azure můžou získat potvrzení o konkrétní transakci pomocí klientské knihovny Azure Confidential Ledger. Následující příklad ukazuje, jak získat potvrzení o zápisu pomocí klientské knihovny pro Python, ale postup je stejný s jakoukoli jinou podporovanou sadou SDK pro Azure Confidential Ledger.
Předpokládáme, že prostředek důvěrné knihy již byl vytvořen pomocí knihovny pro správu důvěrného registru Azure. Pokud ještě nemáte existující prostředek registru, vytvořte ho podle následujících pokynů.
Průvodce kódem
Začneme nastavením importů pro náš program v Pythonu.
import json
# Import the Azure authentication library
from azure.identity import DefaultAzureCredential
# Import the Confidential Ledger Data Plane SDK
from azure.confidentialledger import ConfidentialLedgerClient
from azure.confidentialledger.certificate import ConfidentialLedgerCertificateClient
Následuje konstantní hodnota použitá k nastavení klienta Azure Confidential Ledger. Nezapomeňte konstantu ledger_name
aktualizovat jedinečným názvem vašeho prostředku důvěrného registru.
# Constants for our program
ledger_name = "<your-unique-ledger-name>"
identity_url = "https://identity.confidential-ledger.core.azure.com"
ledger_url = "https://" + ledger_name + ".confidential-ledger.azure.com"
Ověřujeme se pomocí třídy DefaultAzureCredential.
# Setup authentication
credential = DefaultAzureCredential()
Pak získáme a uložíme certifikát služby Důvěrné registru pomocí klienta certifikátu z adresy URL identity důvěrného registru. Certifikát služby je certifikát veřejného klíče síťové identity, který se používá jako kořen důvěryhodnosti pro ověřování serveru TLS . Jinými slovy, používá se jako certifikační autorita (CA) k navázání připojení TLS k libovolnému uzlu v síti CCF.
# Create a Certificate client and use it to
# get the service identity for our ledger
identity_client = ConfidentialLedgerCertificateClient(identity_url)
network_identity = identity_client.get_ledger_identity(
ledger_id=ledger_name
)
# Save network certificate into a file for later use
ledger_tls_cert_file_name = "network_certificate.pem"
with open(ledger_tls_cert_file_name, "w") as cert_file:
cert_file.write(network_identity["ledgerTlsCertificate"])
Dále můžeme použít naše přihlašovací údaje, načtený síťový certifikát a jedinečnou adresu URL registru k vytvoření klienta důvěrného registru.
# Create Confidential Ledger client
ledger_client = ConfidentialLedgerClient(
endpoint=ledger_url,
credential=credential,
ledger_certificate_path=ledger_tls_cert_file_name
)
Pomocí klienta Důvěrné registru můžeme spouštět všechny podporované operace v instanci Registru důvěrných informací Azure. Můžeme například k registru připojit novou položku a počkat na potvrzení odpovídající transakce zápisu.
# The method begin_create_ledger_entry returns a poller that
# we can use to wait for the transaction to be committed
create_entry_poller = ledger_client.begin_create_ledger_entry(
{"contents": "Hello World!"}
)
create_entry_result = create_entry_poller.result()
Po potvrzení transakce můžeme pomocí klienta získat potvrzení o položce připojené k registru v předchozím kroku pomocí příslušného ID transakce.
# The method begin_get_receipt returns a poller that
# we can use to wait for the receipt to be available by the system
get_receipt_poller = ledger_client.begin_get_receipt(
create_entry_result["transactionId"]
)
get_receipt_result = get_receipt_poller.result()
Ukázkový kód
Poskytuje se úplný vzorový kód použitý v názorném postupu kódu.
import json
# Import the Azure authentication library
from azure.identity import DefaultAzureCredential
# Import the Confidential Ledger Data Plane SDK
from azure.confidentialledger import ConfidentialLedgerClient
from azure.confidentialledger.certificate import ConfidentialLedgerCertificateClient
from receipt_verification import verify_receipt
# Constants
ledger_name = "<your-unique-ledger-name>"
identity_url = "https://identity.confidential-ledger.core.azure.com"
ledger_url = "https://" + ledger_name + ".confidential-ledger.azure.com"
# Setup authentication
credential = DefaultAzureCredential()
# Create Ledger Certificate client and use it to
# retrieve the service identity for our ledger
identity_client = ConfidentialLedgerCertificateClient(identity_url)
network_identity = identity_client.get_ledger_identity(ledger_id=ledger_name)
# Save network certificate into a file for later use
ledger_tls_cert_file_name = "network_certificate.pem"
with open(ledger_tls_cert_file_name, "w") as cert_file:
cert_file.write(network_identity["ledgerTlsCertificate"])
# Create Confidential Ledger client
ledger_client = ConfidentialLedgerClient(
endpoint=ledger_url,
credential=credential,
ledger_certificate_path=ledger_tls_cert_file_name,
)
# The method begin_create_ledger_entry returns a poller that
# we can use to wait for the transaction to be committed
create_entry_poller = ledger_client.begin_create_ledger_entry(
{"contents": "Hello World!"}
)
create_entry_result = create_entry_poller.result()
# The method begin_get_receipt returns a poller that
# we can use to wait for the receipt to be available by the system
get_receipt_poller = ledger_client.begin_get_receipt(
create_entry_result["transactionId"]
)
get_receipt_result = get_receipt_poller.result()
# Save fetched receipt into a file
with open("receipt.json", "w") as receipt_file:
receipt_file.write(json.dumps(get_receipt_result, sort_keys=True, indent=2))
Zápis obsahu potvrzení o transakcích
Tady je příklad datové části odpovědi JSON vrácené instancí důvěrného registru Azure při volání koncového GET_RECEIPT
bodu.
{
"receipt": {
"cert": "-----BEGIN CERTIFICATE-----\nMIIB0jCCAXmgAwIBAgIQPxdrEtGY+SggPHETin1XNzAKBggqhkjOPQQDAjAWMRQw\nEgYDVQQDDAtDQ0YgTmV0d29yazAeFw0yMjA3MjAxMzUzMDFaFw0yMjEwMTgxMzUz\nMDBaMBMxETAPBgNVBAMMCENDRiBOb2RlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\nQgAEWy81dFeEZ79gVJnfHiPKjZ54fZvDcFlntFwJN8Wf6RZa3PaV5EzwAKHNfojj\noXT4xNkJjURBN7q+1iE/vvc+rqOBqzCBqDAJBgNVHRMEAjAAMB0GA1UdDgQWBBQS\nwl7Hx2VkkznJNkVZUbZy+TOR/jAfBgNVHSMEGDAWgBTrz538MGI/SdV8k8EiJl5z\nfl3mBTBbBgNVHREEVDBShwQK8EBegjNhcGljY2lvbmUtdGVzdC1sZWRnZXIuY29u\nZmlkZW50aWFsLWxlZGdlci5henVyZS5jb22CFWFwaWNjaW9uZS10ZXN0LWxlZGdl\ncjAKBggqhkjOPQQDAgNHADBEAiAsGawDcYcH/KzF2iK9Ldx/yABUoYSNti2Cyxum\n9RRNKAIgPB/XGh/FQS3nmZLExgBVXkDYdghQu/NCY/hHjQ9AvWg=\n-----END CERTIFICATE-----\n",
"leafComponents": {
"claimsDigest": "0000000000000000000000000000000000000000000000000000000000000000",
"commitEvidence": "ce:2.40:f36ffe2930ec95d50ebaaec26e2bec56835abd051019eb270f538ab0744712a4",
"writeSetDigest": "8452624d10bdd79c408c0f062a1917aa96711ea062c508c745469636ae1460be"
},
"nodeId": "70e995887e3e6b73c80bc44f9fbb6e66b9f644acaddbc9c0483cfc17d77af24f",
"proof": [
{
"left": "b78230f9abb27b9b803a9cae4e4cec647a3be1000fc2241038867792d59d4bc1"
},
{
"left": "a2835d4505b8b6b25a0c06a9c8e96a5204533ceac1edf2b3e0e4dece78fbaf35"
}
],
"signature": "MEUCIQCjtMqk7wOtUTgqlHlCfWRqAco+38roVdUcRv7a1G6pBwIgWKpCSdBmhzgEdwguUW/Cj/Z5bAOA8YHSoLe8KzrlqK8="
},
"state": "Ready",
"transactionId": "2.40"
}
Odpověď JSON obsahuje následující pole na kořenové úrovni.
účtenka: Obsahuje hodnoty, které lze použít k ověření platnosti potvrzení pro odpovídající zápis transakce.
state: Stav vrácené odpovědi JSON. Povolené jsou následující možné hodnoty:
Ready
: Potvrzení vrácené v odpovědi je k dispozici.Loading
: Potvrzení ještě není k dispozici k načtení a žádost se musí opakovat.
transactionId: ID transakce přidružené k potvrzení transakce zápisu.
Pole receipt
obsahuje následující pole.
cert: Řetězec s certifikátem veřejného klíče PEM uzlu CCF, který podepsal transakci zápisu. Certifikát identity služby by měl vždy doporučit certifikát podpisového uzlu. Další podrobnosti o tom, jak se transakce pravidelně podepisují a jak jsou podpisové transakce připojeny k registru v CCF na následujícím odkazu.
nodeId: Šestnáctkový řetězec představující hodnotu hash SHA-256 veřejného klíče podpisového uzlu CCF.
leafComponents: Komponenty hodnoty hash uzlu typu list ve stromu Merkle, které jsou přidruženy k zadané transakci. Merkle Tree je stromová datová struktura, která zaznamenává hodnotu hash každé transakce a zaručuje integritu registru. Další informace o tom, jak se merkle tree používá v CCF, najdete v související dokumentaci CCF.
proof: Seznam párů klíč-hodnota představujících hodnoty hash uzlů Merkle Tree, které v kombinaci s hodnotou hash uzlu typu list odpovídající dané transakci umožňují přepočítání kořenové hodnoty hash stromu. Díky vlastnostem Merkle Tree je možné rekompuovat kořenovou hodnotu hash stromu pouze podmnožinu uzlů. Prvky v tomto seznamu jsou ve formě párů klíč-hodnota: klíče označují relativní pozici s ohledem na nadřazený uzel ve stromu na určité úrovni; hodnoty hash SHA-256 daného uzlu jsou šestnáctkové řetězce.
serviceEndorsements: Seznam řetězců certifikátů kódovaných PEM představujících předchozí certifikáty identit služeb Je možné, že identita služby, která schválila podpisový uzel, není stejná jako identita, která vydala potvrzení. Certifikát služby se například obnoví po zotavení po havárii důvěrného registru. Seznam minulých certifikátů služeb umožňuje auditorům vytvořit řetěz důvěryhodnosti z podpisového uzlu CCF na aktuální certifikát služby.
podpis: Řetězec Base64 představující podpis kořene Merkle Tree v dané transakci podpisem uzlu CCF.
Pole leafComponents
obsahuje následující pole.
claimsDigest: Hexadecimální řetězec představující algoritmus hash SHA-256 deklarace identity aplikace připojené aplikací Důvěrné registru v době, kdy byla transakce provedena. Deklarace identity aplikací se v současné době nepodporují, protože aplikace Důvěrné registru nepřipojí při provádění transakce zápisu žádnou deklaraci identity.
commitEvidence: Jedinečný řetězec vytvořený na transakci odvozený z ID transakce a tajných kódů registru. Další informace o důkazech potvrzení najdete v související dokumentaci CCF.
writeSetDigest: Šestnáctkový řetězec představující hodnotu hash SHA-256 v úložišti klíč-hodnota, který obsahuje všechny klíče a hodnoty zapsané v době dokončení transakce. Další informace o sadě zápisů najdete v související dokumentaci CCF.
Deklarace identit aplikace
Aplikace Azure Confidential Ledger můžou k zápisu transakcí připojit libovolná data označovaná jako deklarace identity aplikací. Tyto deklarace identity představují akce prováděné během operace zápisu. Při připojení k transakci je algoritmus HASH SHA-256 objektu deklarací zahrnut do registru a potvrzen jako součást transakce zápisu. Zahrnutí deklarace identity do transakce zápisu zaručuje, že hodnota hash deklarace identity je podepsána a nelze s tím manipulovat.
Později lze deklarace identity aplikace odhalit ve svém prostém formátu v datové části potvrzení odpovídající stejné transakci, do které byly přidány. Vystavené deklarace identity umožňují uživatelům překomputovat stejnou hodnotu hash deklarací identity, která byla připojena a podepsána v registru během transakce. Hodnota hash deklarací identity se dá použít jako součást procesu ověření potvrzení transakce zápisu a poskytuje uživatelům offline způsob, jak plně ověřit pravost zaznamenaných deklarací identity.
Deklarace identity aplikací se v současné době podporují ve verzi 2023-01-18-preview
preview rozhraní API .
Zápis obsahu potvrzení o transakcích s deklaracemi identity aplikace
Tady je příklad datové části odpovědi JSON vrácené instancí důvěrného registru Azure, která zaznamenala deklarace identity aplikace při volání koncového GET_RECEIPT
bodu.
{
"applicationClaims": [
{
"kind": "LedgerEntry",
"ledgerEntry": {
"collectionId": "subledger:0",
"contents": "Hello world",
"protocol": "LedgerEntryV1",
"secretKey": "Jde/VvaIfyrjQ/B19P+UJCBwmcrgN7sERStoyHnYO0M="
}
}
],
"receipt": {
"cert": "-----BEGIN CERTIFICATE-----\nMIIBxTCCAUygAwIBAgIRAMR89lUNeIghDUfpyHi3QzIwCgYIKoZIzj0EAwMwFjEU\nMBIGA1UEAwwLQ0NGIE5ldHdvcmswHhcNMjMwNDI1MTgxNDE5WhcNMjMwNzI0MTgx\nNDE4WjATMREwDwYDVQQDDAhDQ0YgTm9kZTB2MBAGByqGSM49AgEGBSuBBAAiA2IA\nBB1DiBUBr9/qapmvAIPm1o3o3LRViSOkfFVI4oPrw3SodLlousHrLz+HIe+BqHoj\n4nBjt0KAS2C0Av6Q+Xg5Po6GCu99GQSoSfajGqmjy3j3bwjsGJi5wHh1pNbPmMm/\nTqNhMF8wDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUCPaDohOGjVgQ2Lb8Pmubg7Y5\nDJAwHwYDVR0jBBgwFoAU25KejcEmXDNnKvSLUwW/CQZIVq4wDwYDVR0RBAgwBocE\nfwAAATAKBggqhkjOPQQDAwNnADBkAjA8Ci9myzieoLoIy+7mUswVEjUG3wrEXtxA\nDRmt2PK9bTDo2m3aJ4nCQJtCWQRUlN0CMCMOsXL4NnfsSxaG5CwAVkDwLBUPv7Zy\nLfSh2oZ3Wn4FTxL0UfnJeFOz/CkDUtJI1A==\n-----END CERTIFICATE-----\n",
"leafComponents": {
"claimsDigest": "d08d8764437d09b2d4d07d52293cddaf40f44a3ea2176a0528819a80002df9f6",
"commitEvidence": "ce:2.13:850a25da46643fa41392750b6ca03c7c7d117c27ae14e3322873de6322aa7cd3",
"writeSetDigest": "6637eddb8741ab54cc8a44725be67fd9be390e605f0537e5a278703860ace035"
},
"nodeId": "0db9a22e9301d1167a2a81596fa234642ad24bc742451a415b8d653af056795c",
"proof": [
{
"left": "bcce25aa51854bd15257cfb0c81edc568a5a5fa3b81e7106c125649db93ff599"
},
{
"left": "cc82daa27e76b7525a1f37ed7379bb80f6aab99f2b36e2e06c750dd9393cd51b"
},
{
"left": "c53a15cbcc97e30ce748c0f44516ac3440e3e9cc19db0852f3aa3a3d5554dfae"
}
],
"signature": "MGYCMQClZXVAFn+vflIIikwMz64YZGoH71DKnfMr3LXkQ0lhljSsvDrmtmi/oWwOsqy28PsCMQCMe4n9aXXK4R+vY0SIfRWSCCfaADD6teclFCkVNK4317ep+5ENM/5T/vDJf3V4IvI="
},
"state": "Ready",
"transactionId": "2.13"
}
V porovnání s příkladem účtenky zobrazeným v předchozí části obsahuje odpověď JSON další applicationClaims
pole, které představuje seznam deklarací aplikací zaznamenaných hlavní knihy během transakce zápisu. Každý objekt v applicationClaims
seznamu obsahuje následující pole.
kind: Představuje druh deklarace identity aplikace. Hodnota určuje, jak analyzovat objekt deklarace aplikace pro zadaný typ.
ledgerEntry: Představuje deklaraci identity aplikace odvozené ze vstupních dat registru. Deklarace identity by obsahovala data zaznamenaná aplikací během transakce zápisu (například ID kolekce a obsah poskytnutý uživatelem) a požadované informace pro výpočet hodnoty hash odpovídající jednomu objektu deklarace identity.
digest: Představuje deklaraci identity aplikace v přehledné podobě. Tento objekt deklarace identity by obsahoval předpočítané hodnoty hash aplikací a protokol použitý pro výpočet.
Pole ledgerEntry
obsahuje následující pole.
protokol: Představuje protokol, který se má použít k výpočtu hodnot hash deklarace identity z dat dané deklarace identity.
collectionId: Identifikátor kolekce zapsané během odpovídající transakce zápisu.
obsah: Obsah registru zapsaného během odpovídající transakce zápisu.
secretKey: Tajný klíč kódovaný base64. Tento klíč se použije v algoritmu HMAC s hodnotami zadanými v deklaraci identity aplikace k získání hodnoty hash deklarace identity.
Pole digest
obsahuje následující pole.
protocol: Představuje protokol použitý k výpočtu hodnot hash dané deklarace identity.
value: Hodnota hash deklarace identity aplikace v šestnáctkové podobě. Tato hodnota by musela být hashována s
protocol
hodnotou, aby bylo možné vypočítat úplnou hodnotu hash deklarace identity aplikace.
Další materiály
Další informace o zápisu potvrzení transakcí a o tom, jak CCF zajišťuje integritu každé transakce, najdete na následujících odkazech:
- Zápis účtenek
- Účtenky
- Glosář CCF
- Merkle Tree
- Kryptografie
- Certifikáty
- Deklarace identity aplikací
- Deklarace identity definované uživatelem v účtech