Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die Empfangsbestätigung einer Schreibtransaktion im Azure Confidential Ledger stellt einen kryptografischen Merkle-Nachweis dar, dass die zugehörige Schreibtransaktion vom CCF-Netzwerk global bestätigt wurde. Benutzer von Azure Confidential Ledger können zu jedem Zeitpunkt eine Empfangsbestätigung für eine bestätigte Schreibtransaktion erhalten, um zu überprüfen, ob der entsprechende Schreibvorgang erfolgreich im unveränderlichen Ledger erfasst wurde.
Weitere Informationen zu Empfangsbestätigungen für Schreibtransaktionen in Azure Confidential Ledger finden Sie im entsprechenden Artikel.
Schritte zur Belegverifizierung
Eine Schreibtransaktionsbestätigung kann anhand einer bestimmten Gruppe von Schritten überprüft werden, die in den folgenden Unterabschnitten beschrieben sind. Die gleichen Schritte sind in der CCF-Dokumentation beschrieben.
Blattknotenberechnung
Der erste Schritt besteht darin, den SHA-256-Hash des Blattknotens in der Merkle-Struktur zu berechnen, der der zugesicherten Transaktion entspricht. Ein Blattknoten besteht aus der geordneten Verkettung der folgenden Felder, die unter leafComponents in einem Beleg des Azure Confidential Ledger zu finden sind:
writeSetDigest- SHA-256-Digest von
commitEvidence -
claimsDigestFelder
Diese Werte müssen als Bytearrays verkettet werden: Beide writeSetDigest und claimsDigest müssten aus Zeichenfolgen hexadezimaler Ziffern in Bytearrays konvertiert werden. Andererseits kann der Hash von commitEvidence (als Bytearray) durch Anwenden der SHA-256-Hashfunktion über die UTF-8-codierte commitEvidence Zeichenfolge abgerufen werden.
Der Hash-Digest des Blattknotens kann auf ähnliche Weise berechnet werden, indem die SHA-256-Hashfunktion auf die Ergebnisverkettung der resultierenden Bytes angewendet wird.
Berechnung des Stammknotens
Der zweite Schritt besteht darin, den SHA-256-Hash des Stammes der Merkle-Struktur zum Zeitpunkt des Commits der Transaktion zu berechnen. Die Berechnung erfolgt durch iteratives Verketten und Hashen des Ergebnisses der vorherigen Iteration, beginnend mit dem Blattknoten-Hash, der im vorherigen Schritt berechnet wurde, und den geordneten Knoten-Hashes, die im proof-Feld eines Belegs angegeben sind. Die proof Liste wird als sortierte Liste bereitgestellt, und ihre Elemente müssen in der angegebenen Reihenfolge durchlaufen werden.
Die Verkettung muss für die Bytedarstellung unter Berücksichtigung der relativen Reihenfolge durchgeführt werden, die in den bereitgestellten Objekten im Feld proof angegeben ist (entweder left oder right).
- Wenn der Schlüssel des aktuellen Elements
proofin istleft, sollte das Ergebnis der vorherigen Iteration an den aktuellen Elementwert angefügt werden. - Wenn der Schlüssel des aktuellen Elements in
proofrightist, sollte das Ergebnis der vorherigen Iteration dem aktuellen Elementwert vorangestellt werden.
Nach jeder Verkettung muss die SHA-256-Funktion angewendet werden, um die Eingabe für die nächste Iteration abzurufen. Dieser Vorgang folgt den Standardschritten zum Berechnen des Stammknotens einer Merkle-Struktur mit den erforderlichen Knoten für die Berechnung.
Überprüfen Sie die Signatur über den Stammknoten
Der dritte Schritt besteht darin, zu überprüfen, ob die über den Stammknotenhash erstellte kryptografische Signatur mithilfe des Signaturknotenzertifikats in der Bestätigung gültig ist. Der Überprüfungsprozess folgt den Standardschritten für die Überprüfung digitaler Signaturen für Nachrichten, die mit dem Elliptic Curve Digital Signature Algorithm (ECDSA) signiert wurden. Genauer gesagt sind die Schritte:
- Decodieren Sie die Base64-Zeichenfolge
signaturein ein Bytearray. - Extrahieren Sie den öffentlichen ECDSA-Schlüssel aus dem Signaturknotenzertifikat
cert. - Stellen Sie sicher, dass die Signatur über dem Stamm der Merkle-Struktur (berechnet mit den Anweisungen im vorherigen Unterabschnitt) mithilfe des extrahierten öffentlichen Schlüssels aus dem vorherigen Schritt authentifiziert ist. Dieser Schritt entspricht effektiv einem standardmäßigen Überprüfungsprozess für digitale Signaturen mithilfe von ECDSA. Es gibt viele Bibliotheken in den am häufigsten verwendeten Programmiersprachen, mit denen eine ECDSA-Signatur mithilfe eines Zertifikats für öffentliche Schlüssel über einige Daten überprüft werden kann (z. B. die cryptographiebibliothek für Python).
Überprüfen der Unterstützung des Signaturknotenzertifikats
Zusätzlich zum vorherigen Schritt muss auch verifiziert werden, dass das Zertifikat des signierenden Knotens durch das aktuelle Ledger-Zertifikat genehmigt (d. h. signiert) ist. Dieser Schritt hängt nicht von den anderen drei vorherigen Schritten ab und kann unabhängig von den anderen ausgeführt werden.
Es ist möglich, dass sich die aktuelle Dienstidentität, die den Beleg ausgestellt hat, von der Identität unterscheidet, die den Signaturknoten unterstützt hat (z. B. aufgrund einer Zertifikatverlängerung). In diesem Fall ist es erforderlich, die Vertrauenskette der Zertifikate vom Signaturknotenzertifikat (d. h. das cert Feld im Beleg) bis zur vertrauenswürdigen Stammzertifizierungsstelle (CA) (d. h. dem aktuellen Dienstidentitätszertifikat) über andere vorherige Dienstidentitäten (d. h. das serviceEndorsements Listenfeld im Beleg) zu überprüfen. Die serviceEndorsements Liste wird als sortierte Liste von der ältesten bis zur neuesten Dienstidentität bereitgestellt.
Die Bestätigung des Zertifikats muss für die gesamte Kette überprüft werden und folgt dem genau gleichen digitalen Signaturüberprüfungsprozess, der im vorherigen Unterabschnitt beschrieben ist. Es gibt beliebte open-source-Kryptografiebibliotheken (z. B. OpenSSL), die in der Regel verwendet werden können, um einen Zertifikat-Bestätigungsschritt auszuführen.
Verifizieren des Digest von Anwendungs-Claims
Als optionaler Schritt ist es möglich, für den Fall, dass Anwendungs-Claims einer Bestätigung angefügt sind, den Claims-Digest aus den offengelegten Claims (nach einem bestimmten Algorithmus) zu berechnen und zu verifizieren, dass der Digest mit dem in dem Payload enthaltenen claimsDigest übereinstimmt. Um den Digest aus den zur Verfügung gestellten Claim-Objekten zu berechnen, muss jedes Anwendungs-Claim-Objekt in der Liste durchlaufen werden und sein kind-Feld überprüft werden.
Wenn das Anspruchsobjekt der Art LedgerEntryist, sollte die Ledger-Sammlungs-ID (collectionId) und der Inhalt (contents) des Anspruchs extrahiert und verwendet werden, um ihre HMAC-Digests mithilfe des geheimen Schlüssels (secretKey) zu berechnen, der im Anspruchsobjekt angegeben ist. Diese beiden Digests werden dann verkettet, und der SHA-256-Hash der Verkettung wird berechnet. Das Protokoll (protocol) und der resultierende Anspruchsdatendigest werden dann verkettet, und ein anderer SHA-256-Hash der Verkettung wird berechnet, um den endgültigen Digest abzurufen.
Wenn das Anspruchsobjekt der Art ClaimDigestist, sollte der Anspruchsdigest (value) extrahiert, mit dem Protokoll (protocol) verkettet werden, und der SHA-256-Hash der Verkettung wird berechnet, um den endgültigen Digest abzurufen.
Nach dem Berechnen jedes einzelnen Anspruchsdigests ist es erforderlich, alle berechneten Digests aus jedem Anwendungsanspruchsobjekt zu verketten (in derselben Reihenfolge, in der sie im Beleg angezeigt werden). Der Verkettung sollte dann die Anzahl der verarbeiteten Claims vorangestellt werden. Der SHA-256-Hash der vorangegangenen Verkettung ergibt den endgültigen Digest der Claims, der mit dem im Receipt-Objekt vorhandenen claimsDigest übereinstimmen sollte.
Mehr Ressourcen
Weitere Informationen zum Inhalt eines Schreibtransaktionsbelegs in Azure Confidential Ledger sowie Erläuterungen zu den einzelnen Feldern finden Sie im entsprechenden Artikel. Die CCF-Dokumentation enthält auch weitere Informationen zur Bestätigung des Belegs und zu anderen verwandten Ressourcen unter den folgenden Links:
- Bestätigung des Belegs
- CCF-Glossar
- Merkle-Baum
- Kryptografie
- Bescheinigungen
- Anwendungsansprüche
- Benutzerdefinierte Claims in Receipts
Überprüfen der Belege für Schreibtransaktionen
Belegverifizierungsprogramme
Die Clientbibliothek für das vertrauliche Azure-Hauptbuch für Python stellt Hilfsfunktionen bereit, um Empfangsbestätigungen von Schreibtransaktionen zu überprüfen und den Claims-Digest aus einer Liste von Anwendungs-Claims zu berechnen. Weitere Informationen zur Verwendung des Data Plane SDK und der belegspezifischen Dienstprogramme finden Sie im Abschnitt this section und dieser Beispielcode.
Einrichtung und Voraussetzungen
Zu Referenzzwecken stellen wir Python-Beispielcode bereit, um Belege für Schreibtransaktionen in Azure Confidential Ledger gemäß den im vorherigen Abschnitt beschriebenen Schritten vollständig zu verifizieren.
Um den vollständigen Überprüfungsalgorithmus auszuführen, sind das aktuelle Dienstnetzwerkzertifikat und eine Schreibtransaktionsbestätigung aus einer ausgeführten Azure vertraulichen Ledgerressource erforderlich. Ausführliche Informationen zum Abrufen einer Schreibtransaktionsbestätigung und des Dienstzertifikats aus einer Azure vertraulichen Hauptbuchinstanz finden Sie in diesem Artikel.
Exemplarische Vorgehensweise mit Code
Der folgende Code kann verwendet werden, um die erforderlichen Objekte zu initialisieren und den Bestätigungsalgorithmus auszuführen. Ein separates Hilfsprogramm (verify_receipt) wird verwendet, um den vollständigen Überprüfungsalgorithmus auszuführen, und akzeptiert den Inhalt des receipt Felds in einer GET_RECEIPT Antwort als Wörterbuch und das Dienstzertifikat als einfache Zeichenfolge. Die Funktion löst eine Ausnahme aus, wenn der Beleg nicht gültig ist oder ein Fehler während der Verarbeitung aufgetreten ist.
Es wird davon ausgegangen, dass sowohl der Beleg als auch das Dienstzertifikat aus Dateien geladen werden können. Stellen Sie sicher, dass Sie sowohl die Konstanten service_certificate_file_name als auch receipt_file_name mit den entsprechenden Dateinamen des Dienstzertifikats und des Belegs aktualisieren, die Sie überprüfen möchten.
import json
# Constants
service_certificate_file_name = "<service-certificate-file>"
receipt_file_name = "<receipt-file>"
# Use the receipt and the service identity to verify the receipt content
with open(service_certificate_file_name, "r") as service_certificate_file, open(
receipt_file_name, "r"
) as receipt_file:
# Load relevant files content
receipt = json.loads(receipt_file.read())["receipt"]
service_certificate_cert = service_certificate_file.read()
try:
verify_receipt(receipt, service_certificate_cert)
print("Receipt verification succeeded")
except Exception as e:
print("Receipt verification failed")
# Raise caught exception to look at the error stack
raise e
Da der Überprüfungsprozess einige kryptografische und Hashinggrundtypen erfordert, werden die folgenden Bibliotheken verwendet, um die Berechnung zu vereinfachen.
- Die CCF-Python-Bibliothek: Das Modul stellt eine Reihe von Tools zur Bestätigung des Belegs bereit.
- Die Python Kryptografiebibliothek: eine weit verbreitete Bibliothek, die verschiedene kryptografische Algorithmen und Grundtypen enthält.
- Das modul hashlib, Teil der Python Standardbibliothek: ein Modul, das eine allgemeine Schnittstelle für gängige Hashingalgorithmen bereitstellt.
from ccf.receipt import verify, check_endorsements, root
from cryptography.x509 import load_pem_x509_certificate, Certificate
from hashlib import sha256
from typing import Dict, List, Any
Innerhalb der verify_receipt Funktion überprüfen wir, ob der angegebene Beleg gültig ist und alle erforderlichen Felder enthält.
# Check that all the fields are present in the receipt
assert "cert" in receipt
assert "leafComponents" in receipt
assert "claimsDigest" in receipt["leafComponents"]
assert "commitEvidence" in receipt["leafComponents"]
assert "writeSetDigest" in receipt["leafComponents"]
assert "proof" in receipt
assert "signature" in receipt
Wir initialisieren die Variablen, die im restlichen Programm verwendet werden sollen.
# Set the variables
node_cert_pem = receipt["cert"]
claims_digest_hex = receipt["leafComponents"]["claimsDigest"]
commit_evidence_str = receipt["leafComponents"]["commitEvidence"]
write_set_digest_hex = receipt["leafComponents"]["writeSetDigest"]
proof_list = receipt["proof"]
service_endorsements_certs_pem = receipt.get("serviceEndorsements", [])
root_node_signature = receipt["signature"]
Wir können die PEM-Zertifikate für die Dienstidentität, den Signaturknoten und die Bestätigungen von Zertifikaten aus früheren Dienstidentitäten mithilfe der Kryptografiebibliothek laden.
# Load service and node PEM certificates
service_cert = load_pem_x509_certificate(service_cert_pem.encode())
node_cert = load_pem_x509_certificate(node_cert_pem.encode())
# Load service endorsements PEM certificates
service_endorsements_certs = [
load_pem_x509_certificate(pem.encode())
for pem in service_endorsements_certs_pem
]
Der erste Schritt des Überprüfungsprozesses besteht darin, den Digest des Blattknotens zu berechnen.
# Compute leaf of the Merkle Tree corresponding to our transaction
leaf_node_hex = compute_leaf_node(
claims_digest_hex, commit_evidence_str, write_set_digest_hex
)
Die compute_leaf_node-Funktion akzeptiert als Parameter die Blattkomponenten des Belegs (das claimsDigest, das commitEvidence und das writeSetDigest) und gibt den Blattknotenhash in hexadezimaler Form zurück.
Wie zuvor beschrieben, berechnen wir den Digest von commitEvidence (mit der SHA-256-Funktion hashlib ). Anschließend konvertieren wir sowohl writeSetDigest als auch claimsDigest in Bytearrays. Schließlich verketten wir die drei Arrays und verarbeiten das Ergebnis mithilfe der SHA256-Funktion.
def compute_leaf_node(
claims_digest_hex: str, commit_evidence_str: str, write_set_digest_hex: str
) -> str:
"""Function to compute the leaf node associated to a transaction
given its claims digest, commit evidence, and write set digest."""
# Digest commit evidence string
commit_evidence_digest = sha256(commit_evidence_str.encode()).digest()
# Convert write set digest to bytes
write_set_digest = bytes.fromhex(write_set_digest_hex)
# Convert claims digest to bytes
claims_digest = bytes.fromhex(claims_digest_hex)
# Create leaf node by hashing the concatenation of its three components
# as bytes objects in the following order:
# 1. write_set_digest
# 2. commit_evidence_digest
# 3. claims_digest
leaf_node_digest = sha256(
write_set_digest + commit_evidence_digest + claims_digest
).digest()
# Convert the result into a string of hexadecimal digits
return leaf_node_digest.hex()
Nach dem Berechnen des Blatts können wir die Wurzel des Merkle-Baumes berechnen.
# Compute root of the Merkle Tree
root_node = root(leaf_node_hex, proof_list)
Wir verwenden die Funktion root, die als Teil der CCF-Python-Bibliothek bereitgestellt wird. Die Funktion verkettet das Ergebnis der vorherigen Iteration nacheinander mit einem neuen Element aus proof, verarbeitet die Verkettung und wiederholt dann den Schritt für jedes Element in proof mit dem zuvor berechneten Digest. Die Verkettung muss die Reihenfolge der Knoten im Merkle-Baum respektieren, um sicherzustellen, dass die Wurzel richtig komputiert wird.
def root(leaf: str, proof: List[dict]):
"""
Recompute root of Merkle tree from a leaf and a proof of the form:
[{"left": digest}, {"right": digest}, ...]
"""
current = bytes.fromhex(leaf)
for n in proof:
if "left" in n:
current = sha256(bytes.fromhex(n["left"]) + current).digest()
else:
current = sha256(current + bytes.fromhex(n["right"])).digest()
return current.hex()
Nach dem Berechnen des Stammknotenhashs können wir die Signatur überprüfen, die im Beleg über dem Stamm enthalten ist, um zu überprüfen, ob die Signatur korrekt ist.
# Verify signature of the signing node over the root of the tree
verify(root_node, root_node_signature, node_cert)
Ebenso stellt die CCF-Bibliothek eine Funktion verify bereit, um diese Überprüfung durchzuführen. Wir verwenden den öffentlichen ECDSA-Schlüssel des Signaturknotenzertifikats, um die Signatur über den Stamm des Baums zu überprüfen.
def verify(root: str, signature: str, cert: Certificate):
"""
Verify signature over root of Merkle Tree
"""
sig = base64.b64decode(signature)
pk = cert.public_key()
assert isinstance(pk, ec.EllipticCurvePublicKey)
pk.verify(
sig,
bytes.fromhex(root),
ec.ECDSA(utils.Prehashed(hashes.SHA256())),
)
Der letzte Schritt der Quittungsüberprüfung besteht darin, das Zertifikat zu validieren, das verwendet wurde, um die Wurzel der Merkle-Struktur zu signieren.
# Verify node certificate is endorsed by the service certificates through endorsements
check_endorsements(node_cert, service_cert, service_endorsements_certs)
Ebenso können wir das CCF-Hilfsprogramm check_endorsements verwenden, um zu überprüfen, ob die Dienstidentität den Signaturknoten unterstützt. Die Zertifikatkette könnte aus früheren Dienstzertifikaten bestehen, daher sollten wir überprüfen, ob die Bestätigung transitiv angewendet wird, wenn serviceEndorsements es sich nicht um eine leere Liste handelt.
def check_endorsement(endorsee: Certificate, endorser: Certificate):
"""
Check endorser has endorsed endorsee
"""
digest_algo = endorsee.signature_hash_algorithm
assert digest_algo
digester = hashes.Hash(digest_algo)
digester.update(endorsee.tbs_certificate_bytes)
digest = digester.finalize()
endorser_pk = endorser.public_key()
assert isinstance(endorser_pk, ec.EllipticCurvePublicKey)
endorser_pk.verify(
endorsee.signature, digest, ec.ECDSA(utils.Prehashed(digest_algo))
)
def check_endorsements(
node_cert: Certificate, service_cert: Certificate, endorsements: List[Certificate]
):
"""
Check a node certificate is endorsed by a service certificate, transitively through a list of endorsements.
"""
cert_i = node_cert
for endorsement in endorsements:
check_endorsement(cert_i, endorsement)
cert_i = endorsement
check_endorsement(cert_i, service_cert)
Alternativ können wir das Zertifikat auch mithilfe der OpenSSL-Bibliothek mit einer ähnlichen Methode überprüfen.
from OpenSSL.crypto import (
X509,
X509Store,
X509StoreContext,
)
def verify_openssl_certificate(
node_cert: Certificate,
service_cert: Certificate,
service_endorsements_certs: List[Certificate],
) -> None:
"""Verify that the given node certificate is a valid OpenSSL certificate through
the service certificate and a list of endorsements certificates."""
store = X509Store()
# pyopenssl does not support X509_V_FLAG_NO_CHECK_TIME. For recovery of expired
# services and historical receipts, we want to ignore the validity time. 0x200000
# is the bitmask for this option in more recent versions of OpenSSL.
X509_V_FLAG_NO_CHECK_TIME = 0x200000
store.set_flags(X509_V_FLAG_NO_CHECK_TIME)
# Add service certificate to the X.509 store
store.add_cert(X509.from_cryptography(service_cert))
# Prepare X.509 endorsement certificates
certs_chain = [X509.from_cryptography(cert) for cert in service_endorsements_certs]
# Prepare X.509 node certificate
node_cert_pem = X509.from_cryptography(node_cert)
# Create X.509 store context and verify its certificate
ctx = X509StoreContext(store, node_cert_pem, certs_chain)
ctx.verify_certificate()
Beispielcode
Der vollständige Beispielcode, der im Code-Durchgang verwendet wird, wird bereitgestellt.
Hauptprogramm
import json
# Use the receipt and the service identity to verify the receipt content
with open("network_certificate.pem", "r") as service_certificate_file, open(
"receipt.json", "r"
) as receipt_file:
# Load relevant files content
receipt = json.loads(receipt_file.read())["receipt"]
service_certificate_cert = service_certificate_file.read()
try:
verify_receipt(receipt, service_certificate_cert)
print("Receipt verification succeeded")
except Exception as e:
print("Receipt verification failed")
# Raise caught exception to look at the error stack
raise e
Bestätigung des Belegs
from cryptography.x509 import load_pem_x509_certificate, Certificate
from hashlib import sha256
from typing import Dict, List, Any
from OpenSSL.crypto import (
X509,
X509Store,
X509StoreContext,
)
from ccf.receipt import root, verify, check_endorsements
def verify_receipt(receipt: Dict[str, Any], service_cert_pem: str) -> None:
"""Function to verify that a given write transaction receipt is valid based
on its content and the service certificate.
Throws an exception if the verification fails."""
# Check that all the fields are present in the receipt
assert "cert" in receipt
assert "leafComponents" in receipt
assert "claimsDigest" in receipt["leafComponents"]
assert "commitEvidence" in receipt["leafComponents"]
assert "writeSetDigest" in receipt["leafComponents"]
assert "proof" in receipt
assert "signature" in receipt
# Set the variables
node_cert_pem = receipt["cert"]
claims_digest_hex = receipt["leafComponents"]["claimsDigest"]
commit_evidence_str = receipt["leafComponents"]["commitEvidence"]
write_set_digest_hex = receipt["leafComponents"]["writeSetDigest"]
proof_list = receipt["proof"]
service_endorsements_certs_pem = receipt.get("serviceEndorsements", [])
root_node_signature = receipt["signature"]
# Load service and node PEM certificates
service_cert = load_pem_x509_certificate(service_cert_pem.encode())
node_cert = load_pem_x509_certificate(node_cert_pem.encode())
# Load service endorsements PEM certificates
service_endorsements_certs = [
load_pem_x509_certificate(pem.encode())
for pem in service_endorsements_certs_pem
]
# Compute leaf of the Merkle Tree
leaf_node_hex = compute_leaf_node(
claims_digest_hex, commit_evidence_str, write_set_digest_hex
)
# Compute root of the Merkle Tree
root_node = root(leaf_node_hex, proof_list)
# Verify signature of the signing node over the root of the tree
verify(root_node, root_node_signature, node_cert)
# Verify node certificate is endorsed by the service certificates through endorsements
check_endorsements(node_cert, service_cert, service_endorsements_certs)
# Alternative: Verify node certificate is endorsed by the service certificates through endorsements
verify_openssl_certificate(node_cert, service_cert, service_endorsements_certs)
def compute_leaf_node(
claims_digest_hex: str, commit_evidence_str: str, write_set_digest_hex: str
) -> str:
"""Function to compute the leaf node associated to a transaction
given its claims digest, commit evidence, and write set digest."""
# Digest commit evidence string
commit_evidence_digest = sha256(commit_evidence_str.encode()).digest()
# Convert write set digest to bytes
write_set_digest = bytes.fromhex(write_set_digest_hex)
# Convert claims digest to bytes
claims_digest = bytes.fromhex(claims_digest_hex)
# Create leaf node by hashing the concatenation of its three components
# as bytes objects in the following order:
# 1. write_set_digest
# 2. commit_evidence_digest
# 3. claims_digest
leaf_node_digest = sha256(
write_set_digest + commit_evidence_digest + claims_digest
).digest()
# Convert the result into a string of hexadecimal digits
return leaf_node_digest.hex()
def verify_openssl_certificate(
node_cert: Certificate,
service_cert: Certificate,
service_endorsements_certs: List[Certificate],
) -> None:
"""Verify that the given node certificate is a valid OpenSSL certificate through
the service certificate and a list of endorsements certificates."""
store = X509Store()
# pyopenssl does not support X509_V_FLAG_NO_CHECK_TIME. For recovery of expired
# services and historical receipts, we want to ignore the validity time. 0x200000
# is the bitmask for this option in more recent versions of OpenSSL.
X509_V_FLAG_NO_CHECK_TIME = 0x200000
store.set_flags(X509_V_FLAG_NO_CHECK_TIME)
# Add service certificate to the X.509 store
store.add_cert(X509.from_cryptography(service_cert))
# Prepare X.509 endorsement certificates
certs_chain = [X509.from_cryptography(cert) for cert in service_endorsements_certs]
# Prepare X.509 node certificate
node_cert_pem = X509.from_cryptography(node_cert)
# Create X.509 store context and verify its certificate
ctx = X509StoreContext(store, node_cert_pem, certs_chain)
ctx.verify_certificate()
Nächste Schritte
- Empfangsbestätigungen für Schreibtransaktionen in Azure Confidential Ledger
- Verwenden Sie den Azure-Portal-Ledger-Explorer, um Transaktionen zu überprüfen
- Untersuchen von Ledger-Daten mit Ledger Explorer (Offline)
- Übersicht über Microsoft Azure Confidential Ledger
- Azure Confidential Ledger-Architektur