Potvrzení o transakcích zápisu do služby Azure Confidential Ledger

Aby bylo možné vynutit záruky integrity transakcí, azure Confidential Ledger používá strukturu dat merkleového stromu 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é služby Azure Confidential Ledger získat kryptografický merkleový důkaz 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í transakce zápisu je důkazem, ž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í transakce zápisu

Nastavení a požadavky

Uživatelé služby Azure Confidential Ledger 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ý jako u jakékoli jiné podporované sady SDK pro Azure Confidential Ledger.

Předpokládáme, že prostředek Confidential Ledger už byl vytvořen pomocí knihovny pro správu Azure Confidential Ledger. 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ásledují konstantní hodnoty použité k nastavení klienta Azure Confidential Ledger. Nezapomeňte konstantu ledger_name aktualizovat jedinečným názvem prostředku Confidential Ledger.

# 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 pomocí třídy DefaultAzureCredential.

# Setup authentication 
credential = DefaultAzureCredential() 

Pak získáme a uložíme certifikát služby Confidential Ledger pomocí klienta certifikátu z adresy URL identity důvěrné knihy. Certifikát služby je certifikát veřejného klíče síťové identity, který se používá jako důvěryhodný kořen pro ověřování serveru TLS . Jinými slovy se používá jako certifikační autorita (CA) pro 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 Confidential Ledger.

# Create Confidential Ledger client 
ledger_client = ConfidentialLedgerClient( 
     endpoint=ledger_url,  
     credential=credential, 
     ledger_certificate_path=ledger_tls_cert_file_name 
) 

Pomocí klienta Confidential Ledger můžeme spouštět všechny podporované operace v instanci Azure Confidential Ledger. Do registru můžeme například 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ázka kódu

K dispozici je úplný ukázkový kód použitý v návodu ke 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í transakce

Tady je příklad datové části odpovědi JSON vrácené instancí Azure Confidential Ledger 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.

  • receipt: Obsahuje hodnoty, které lze použít k ověření platnosti potvrzení pro odpovídající transakci zápisu.

  • state: Stav vrácené odpovědi JSON. Níže jsou uvedené možné povolené hodnoty:

    • Ready: Potvrzení vrácené v odpovědi je k dispozici.
    • Loading: Potvrzení ještě není možné načíst 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 schvalovat certifikát podpisového uzlu. Další podrobnosti o tom, jak se transakce pravidelně podepisují a jak se transakce podpisů připojují do registru v CCF, najdete na následujícím odkazu.

  • nodeId: Hexadecimální řetězec představující hodnotu hash SHA-256 z veřejného klíče podpisového uzlu CCF.

  • leafComponents: Komponenty hodnoty hash uzlu listu v merkle stromu , 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 KE CCF.

  • proof: Seznam párů klíč-hodnota představujících hodnoty hash uzlů merkle tree, které v kombinaci s hodnotou hash listového uzlu odpovídající dané transakci umožňují přepočítání kořenové hodnoty hash stromu. Díky vlastnostem Merkle Tree je možné přepočítat kořenovou hodnotu hash stromu pouze v podmnožině uzlů. Prvky v tomto seznamu jsou ve formě párů klíč-hodnota: klíče označují relativní pozici vzhledem k nadřazeného uzlu ve stromu na určité úrovni; hodnoty jsou hodnoty hash SHA-256 daného uzlu jako šestnáctkové řetězce.

  • serviceEndorsements: Seznam řetězců certifikátů s kódováním PEM představujících předchozí certifikáty identit služby. Je možné, že identita služby, která podpisový uzel schválila, není stejná jako identita, která vystavila potvrzení. Například certifikát služby se obnoví po zotavení po havárii důvěrného registru. Seznam minulých certifikátů služby umožňuje auditorům vytvořit řetěz důvěryhodnosti od podpisového uzlu CCF k aktuálnímu certifikátu služby.

  • signature: Řetězec Base64 představující podpis kořenového stromu Merkle v dané transakci podpisovým uzlem CCF.

Pole leafComponents obsahuje následující pole.

  • claimsDigest: Hexadecimální řetězec představující hodnotu hash SHA-256 deklarace identity aplikace připojené aplikací Confidential Ledger v době provedení transakce. Deklarace identity aplikací nejsou aktuálně podporované, protože aplikace Confidential Ledger při provádění transakce zápisu nepřipojí žádnou deklaraci identity.

  • commitEvidence: Jedinečný řetězec vytvořený pro každou transakci odvozený z ID transakce a tajných kódů registru. Další informace o důkazech o potvrzení najdete v související dokumentaci CCF.

  • writeSetDigest: Hexadecimální řetězec představující hodnotu hash SHA-256 úložiště klíč-hodnota, která obsahuje všechny klíče a hodnoty zapsané v době dokončení transakce. Další informace o sadě zápisu najdete v související dokumentaci CCF.

Deklarace identity 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 hlavní knihy a potvrzen jako součást transakce zápisu. Zahrnutí deklarace identity do transakce zápisu zaručuje, že souhrn deklarací deklarací identity je podepsán na místě a nebude možné s tím manipulovat.

Později se deklarace identity aplikace můžou zobrazit v 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řepočítat stejný souhrn deklarací deklarací identity, který byl připojen a podepsán v registru během transakce. Souhrn deklarací identity lze použít jako součást procesu ověřování potvrzení o zápisu transakce, což uživatelům poskytuje 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-previewPreview rozhraní API .

Zápis obsahu potvrzení transakce pomocí deklarací identity aplikace

Tady je příklad datové části odpovědi JSON vrácené instancí Azure Confidential Ledger, 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 příjmu zobrazeným v předchozí části obsahuje odpověď JSON další applicationClaims pole, které představuje seznam deklarací identity aplikací zaznamenaných v registru během transakce zápisu. Každý objekt v applicationClaims seznamu obsahuje následující pole.

  • kind: Představuje druh deklarace identity aplikace. Hodnota označuje, jak analyzovat objekt deklarace identity aplikace pro zadaný typ.

  • ledgerEntry: Představuje deklaraci identity aplikace odvozenou ze vstupních dat hlavní knihy. 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 aplikace 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 souhrnu deklarací identity z daných dat deklarace identity.

  • collectionId: Identifikátor kolekce zapsaný během odpovídající transakce zápisu.

  • contents: Obsah knihy zapsaný během odpovídající transakce zápisu.

  • secretKey: Tajný klíč s kódováním base64. Tento klíč se použije v algoritmu HMAC s hodnotami zadanými v deklaraci identity aplikace k získání souhrnu deklarací deklarací identity.

Pole digest obsahuje následující pole.

  • protokol: 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 se musela zatřiďovat s protocol hodnotou, aby bylo možné vypočítat úplný algoritmus hash deklarace identity aplikace.

Další zdroje informací

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:

Další kroky