Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Para aplicar garantías de integridad de transacciones, un libro de contabilidad confidencial Azure usa una estructura de datos de árbol de Merkle para registrar el hash de todos los bloques de transacciones que se anexan al libro de contabilidad inmutable. Una vez confirmada una transacción de escritura, los usuarios de Azure Confidential Ledger pueden obtener una prueba criptográfica de Merkle, o comprobante, de la entrada generada en Azure Confidential Ledger para verificar que la operación de escritura se guardó correctamente. Un recibo de transacción de escritura es una prueba de que el sistema ha confirmado la transacción correspondiente y se puede usar para comprobar que la entrada se ha anexado eficazmente al libro de contabilidad.
Puede encontrar más detalles sobre cómo se usa un árbol de Merkle en un libro de contabilidad confidencial de Azure en la documentación de CCF.
Obtención de recibos de transacciones de escritura
Configuración y requisitos previos
Los usuarios de Azure confidential ledger client library pueden obtener un comprobante para una transacción específica mediante la biblioteca cliente de Azure Confidential Ledger. En el ejemplo siguiente se muestra cómo obtener un recibo de escritura con la biblioteca cliente para Python, pero los pasos son los mismos con cualquiera de los otros SDK compatibles de Azure Confidential Ledger.
Se supone que ya se ha creado un recurso de libro de contabilidad confidencial Azure mediante la biblioteca de administración del libro de contabilidad confidencial Azure. Si aún no tiene un recurso de libro de contabilidad existente, cree uno con las instrucciones siguientes.
Tutorial de código
Empezamos configurando las importaciones para nuestro programa de Python.
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
A continuación se muestran los valores constantes que se usan para configurar el cliente de libro de contabilidad confidencial Azure. Asegúrese de actualizar la ledger_name constante con el nombre único del recurso de libro de contabilidad confidencial de Azure.
# Constants for our program
ledger_name = "<ledger-name>"
identity_url = "https://identity.confidential-ledger.core.azure.com"
ledger_url = "https://" + ledger_name + ".confidential-ledger.azure.com"
Se autentica mediante la clase DefaultAzureCredential.
# Setup authentication
credential = DefaultAzureCredential()
A continuación, obtenemos y guardamos el certificado del servicio de libro de contabilidad confidencial Azure mediante el cliente de certificado de la dirección URL de identidad del libro de contabilidad confidencial de Azure. El certificado de servicio es un certificado de clave pública de identidad de red que se usa como raíz de confianza para la autenticación del servidor TLS . Es decir, se usa como entidad de certificación (CA) para establecer una conexión TLS con cualquiera de los nodos de la red 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"])
A continuación, podemos usar nuestras credenciales, el certificado de red capturado y nuestra dirección URL de libro de contabilidad única para crear un cliente de libro de contabilidad confidencial Azure.
# Create Confidential Ledger client
ledger_client = ConfidentialLedgerClient(
endpoint=ledger_url,
credential=credential,
ledger_certificate_path=ledger_tls_cert_file_name
)
Con el cliente de libro de contabilidad confidencial Azure, podemos ejecutar cualquier operación compatible en una instancia de libro de contabilidad confidencial Azure. Por ejemplo, podemos anexar una nueva entrada al libro de contabilidad y esperar a que se confirme la transacción de escritura correspondiente.
# 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()
Una vez confirmada la transacción, podemos usar el cliente para obtener un recibo sobre la entrada anexada al libro de contabilidad en el paso anterior mediante el identificador de transacción correspondiente.
# 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()
Código de ejemplo
Se proporciona el código de ejemplo completo que se usa en el tutorial de código.
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 = "<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))
Escribir contenido de recibo de transacción
Este es un ejemplo de una carga de respuesta JSON devuelta por una instancia de libro de contabilidad confidencial Azure al llamar al GET_RECEIPT punto de conexión.
{
"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"
}
La respuesta JSON contiene los siguientes campos en el nivel raíz.
receipt: contiene los valores que se pueden usar para comprobar la validez del recibo de la transacción de escritura correspondiente.
state: el estado de la respuesta JSON devuelta. A continuación se muestran los valores posibles permitidos:
-
Ready: el recibo devuelto en la respuesta está disponible. -
Loading: El recibo aún no está disponible para su recuperación y se debe volver a intentar la solicitud.
-
transactionId: identificador de transacción asociado al recibo de transacción de escritura.
El receipt campo contiene los campos siguientes.
cert: cadena con el certificado de clave pública PEM del nodo CCF que firmó la transacción de escritura. El certificado de identidad de servicio siempre debe aprobar el certificado del nodo de firma. Consulte también más detalles sobre cómo las transacciones se firman periódicamente y cómo se anexan las transacciones de firma al libro de contabilidad en CCF en el vínculo siguiente.
nodeId: cadena hexadecimal que representa el resumen hash SHA-256 de la clave pública del nodo CCF de firma.
leafComponents: los componentes del hash del nodo hoja en el árbol de Merkle que están asociados a la transacción especificada. Un árbol merkle es una estructura de datos de árbol que registra el hash de cada transacción y garantiza la integridad del libro de contabilidad. Para obtener más información sobre cómo se usa un árbol merkle en CCF, consulte la documentación relacionada de CCF.
proof: lista de pares clave-valor que representan los hashes de los nodos del árbol de Merkle que, al combinarse con el hash del nodo hoja correspondiente a la transacción dada, permiten recalcular el hash de la raíz del árbol. Gracias a las propiedades de un árbol de Merkle, es posible recalcular el hash de la raíz del árbol usando solo un subconjunto de nodos. Los elementos de esta lista están en forma de pares clave-valor: las claves indican la posición relativa con respecto al nodo primario del árbol en un determinado nivel; los valores son los resúmenes hash SHA-256 del nodo especificados, como cadenas hexadecimales.
serviceEndorsements: lista de cadenas de certificados con codificación PEM que representan certificados de identidades de servicio anteriores. Es posible que la identidad del servicio que aprobó el nodo de firma no sea la misma que la que emitió el recibo. Por ejemplo, el certificado de servicio se renueva después de una recuperación ante desastres de un libro de contabilidad confidencial de Azure. La lista de certificados de servicio anteriores permite a los auditores crear la cadena de confianza desde el nodo de firma ccF al certificado de servicio actual.
firma: cadena base64 que representa la firma de la raíz del árbol de Merkle en la transacción especificada, mediante el nodo CCF de firma.
El leafComponents campo contiene los campos siguientes.
claimsDigest: cadena hexadecimal que representa el resumen hash SHA-256 de la notificación de aplicación adjuntada por la aplicación Azure aplicación de libro de contabilidad confidencial en el momento en que se ejecutó la transacción. Para adjuntar notificaciones de aplicación, consulte la sección Notificaciones de aplicación .
commitEvidence: una cadena única generada por transacción, derivada del identificador de transacción y los secretos del libro de contabilidad. Para obtener más información sobre la evidencia de confirmación, consulte la documentación relacionada de CCF.
writeSetDigest: cadena hexadecimal que representa el resumen hash SHA-256 del almacén deKey-Value, que contiene todas las claves y valores escritos en el momento en que se completó la transacción. Para obtener más información sobre el write set, consulte la documentación de CCF relacionada.
Declaraciones de la aplicación
Azure aplicaciones de libro de contabilidad confidencial pueden adjuntar datos arbitrarios, denominados notificaciones de aplicación, para escribir transacciones. Estos claims representan las acciones ejecutadas durante una operación de escritura. Al adjuntarse a una transacción, el resumen SHA-256 del objeto de declaraciones se incluye en el libro mayor y se registra como parte de la transacción de escritura. La inclusión de la notificación en la transacción de escritura garantiza que el resumen de notificación está firmado y no se puede alterar.
Más adelante, las declaraciones de la aplicación pueden mostrarse en formato de texto sin formato en la carga útil del recibo correspondiente a la misma transacción en la que se añadieron. Las declaraciones expuestas permiten a los usuarios recalcular el mismo resumen de declaraciones que el libro mayor adjuntó y firmó in situ durante la transacción. El resumen de declaraciones se puede utilizar como parte del proceso de verificación del recibo de una transacción de escritura, proporcionando un método sin conexión para que los usuarios verifiquen plenamente la autenticidad de las declaraciones registradas.
Las reclamaciones de aplicación se admiten actualmente en la versión preliminar de la API 2023-01-18-preview.
Escribir el contenido del recibo de la transacción con declaraciones de la aplicación
A continuación, se muestra un ejemplo de una carga útil de respuesta JSON devuelta por una instancia de Azure Confidential Ledger que registró reclamaciones de aplicación al llamar al punto de conexión GET_RECEIPT.
{
"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"
}
En comparación con el ejemplo de recibo que se muestra en la sección anterior, la respuesta JSON contiene otro campo applicationClaims que representa la lista de declaraciones de la aplicación registradas por el libro mayor durante la transacción de escritura. Cada objeto de la applicationClaims lista contiene los siguientes campos.
kind: Representa el tipo de la reclamación de la aplicación. El valor indica cómo analizar el objeto de declaración de la aplicación para el tipo proporcionado.
ledgerEntry: representa una notificación de aplicación derivada de los datos de entrada del libro de contabilidad. La notificación contendrá los datos registrados por la aplicación durante una transacción de escritura (por ejemplo, el identificador de colección y el contenido proporcionado por el usuario) y la información necesaria para calcular el resumen correspondiente al objeto de notificación único.
digest: representa una declaración de aplicación en forma resumida. Este objeto de claim contendría el resumen precomputado por la aplicación y el protocolo empleado para el cálculo.
El ledgerEntry campo contiene los campos siguientes.
protocol: representa el protocolo que se va a usar para calcular el resumen de una notificación a partir de los datos de notificación especificados.
collectionId: identificador de la colección escrita durante la transacción de escritura correspondiente.
contents: el contenido del libro de contabilidad escrito durante la transacción de escritura correspondiente.
secretKey: clave secreta codificada en base64. Esta clave debe utilizarse en el algoritmo HMAC junto con los valores proporcionados en la declaración de la aplicación para obtener el resumen de la declaración.
El digest campo contiene los campos siguientes.
protocol: representa el protocolo usado para calcular el resumen de la notificación especificada.
value: resumen de la notificación de aplicación, en formato hexadecimal. Habría que aplicarle una función hash a este valor junto con el valor
protocolpara calcular el resumen criptográfico completo de la declaración de la aplicación.
Más recursos
Para obtener más información sobre la escritura de recibos de transacciones y cómo CCF garantiza la integridad de cada transacción, consulte los vínculos siguientes:
- Recibos de escritura
- Receipts
- Glosario de CCF
- árbol de Merkle
- Criptografía
- Certificates
- Reclamaciones de aplicación
- ** Declaraciones definidas por el usuario en recibos
Pasos siguientes
- Verificar los recibos de transacciones de escritura del libro de contabilidad confidencial de Azure
- Use el explorador del libro de contabilidad del portal de Azure para comprobar las transacciones
- Inspección de los datos del libro de contabilidad con el Explorador de libro de contabilidad (sin conexión)
- Introducción a Microsoft Azure Confidential Ledger
- Arquitectura de Azure Confidential Ledger