As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Etapa 7: verificar um documento em um ledger
Importante
Aviso de fim do suporte: os clientes existentes poderão usar a Amazon QLDB até o final do suporte em 31/07/2025. Para obter mais detalhes, consulte Migrar um Amazon QLDB Ledger para o Amazon Aurora Postgre
Com a AmazonQLDB, você pode verificar com eficiência a integridade de um documento no diário do seu livro contábil usando hash criptográfico com -256. SHA Para saber mais sobre como a verificação e o hashing criptográfico funcionam emQLDB, consulte. Verificação de dados na Amazon QLDB
Nesta etapa, você verifica uma revisão do documento na tabela VehicleRegistration
do seu ledger vehicle-registration
. Primeiro, você solicita um resumo, que é retornado como um arquivo de saída e atua como uma assinatura de todo o histórico de alterações do seu ledger. Em seguida, você solicita uma prova da revisão em relação a esse resumo. Usando essa prova, a integridade da sua revisão é verificada se todas as verificações de validação forem aprovadas.
Para verificar a revisão de um documento
-
Examine os
.java
arquivos a seguir, que representam QLDB objetos necessários para verificação e classes utilitárias com métodos auxiliares para valores de íon e string.-
BlockAddress.java
/* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package software.amazon.qldb.tutorial.qldb; import java.util.Objects; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; /** * Represents the BlockAddress field of a QLDB document. */ public final class BlockAddress { private static final Logger log = LoggerFactory.getLogger(BlockAddress.class); private final String strandId; private final long sequenceNo; @JsonCreator public BlockAddress(@JsonProperty("strandId") final String strandId, @JsonProperty("sequenceNo") final long sequenceNo) { this.strandId = strandId; this.sequenceNo = sequenceNo; } public long getSequenceNo() { return sequenceNo; } public String getStrandId() { return strandId; } @Override public String toString() { return "BlockAddress{" + "strandId='" + strandId + '\'' + ", sequenceNo=" + sequenceNo + '}'; } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } BlockAddress that = (BlockAddress) o; return sequenceNo == that.sequenceNo && strandId.equals(that.strandId); } @Override public int hashCode() { // CHECKSTYLE:OFF - Disabling as we are generating a hashCode of multiple properties. return Objects.hash(strandId, sequenceNo); // CHECKSTYLE:ON } }
-
Proof.java
/* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package software.amazon.qldb.tutorial.qldb; import com.amazon.ion.IonReader; import com.amazon.ion.IonSystem; import com.amazon.ion.system.IonSystemBuilder; import com.amazonaws.services.qldb.model.GetRevisionRequest; import com.amazonaws.services.qldb.model.GetRevisionResult; import java.util.ArrayList; import java.util.List; /** * A Java representation of the {@link Proof} object. * Returned from the {@link com.amazonaws.services.qldb.AmazonQLDB#getRevision(GetRevisionRequest)} api. */ public final class Proof { private static final IonSystem SYSTEM = IonSystemBuilder.standard().build(); private List<byte[]> internalHashes; public Proof(final List<byte[]> internalHashes) { this.internalHashes = internalHashes; } public List<byte[]> getInternalHashes() { return internalHashes; } /** * Decodes a {@link Proof} from an ion text String. This ion text is returned in * a {@link GetRevisionResult#getProof()} * * @param ionText * The ion text representing a {@link Proof} object. * @return {@link JournalBlock} parsed from the ion text. * @throws IllegalStateException if failed to parse the {@link Proof} object from the given ion text. */ public static Proof fromBlob(final String ionText) { try { IonReader reader = SYSTEM.newReader(ionText); List<byte[]> list = new ArrayList<>(); reader.next(); reader.stepIn(); while (reader.next() != null) { list.add(reader.newBytes()); } return new Proof(list); } catch (Exception e) { throw new IllegalStateException("Failed to parse a Proof from byte array"); } } }
-
QldbIonUtils.java
/* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package software.amazon.qldb.tutorial.qldb; import com.amazon.ion.IonReader; import com.amazon.ion.IonValue; import com.amazon.ionhash.IonHashReader; import com.amazon.ionhash.IonHashReaderBuilder; import com.amazon.ionhash.MessageDigestIonHasherProvider; import software.amazon.qldb.tutorial.Constants; public class QldbIonUtils { private static MessageDigestIonHasherProvider ionHasherProvider = new MessageDigestIonHasherProvider("SHA-256"); private QldbIonUtils() {} /** * Builds a hash value from the given {@link IonValue}. * * @param ionValue * The {@link IonValue} to hash. * @return a byte array representing the hash value. */ public static byte[] hashIonValue(final IonValue ionValue) { IonReader reader = Constants.SYSTEM.newReader(ionValue); IonHashReader hashReader = IonHashReaderBuilder.standard() .withHasherProvider(ionHasherProvider) .withReader(reader) .build(); while (hashReader.next() != null) { } return hashReader.digest(); } }
-
QldbStringUtils.java
/* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package software.amazon.qldb.tutorial.qldb; import com.amazon.ion.IonWriter; import com.amazon.ion.system.IonReaderBuilder; import com.amazon.ion.system.IonTextWriterBuilder; import com.amazonaws.services.qldb.model.GetBlockResult; import com.amazonaws.services.qldb.model.GetDigestResult; import com.amazonaws.services.qldb.model.ValueHolder; import java.io.IOException; /** * Helper methods to pretty-print certain QLDB response types. */ public class QldbStringUtils { private QldbStringUtils() {} /** * Returns the string representation of a given {@link ValueHolder}. * Adapted from the AWS SDK autogenerated {@code toString()} method, with sensitive values un-redacted. * Additionally, this method pretty-prints any IonText included in the {@link ValueHolder}. * * @param valueHolder the {@link ValueHolder} to convert to a String. * @return the String representation of the supplied {@link ValueHolder}. */ public static String toUnredactedString(ValueHolder valueHolder) { StringBuilder sb = new StringBuilder(); sb.append("{"); if (valueHolder.getIonText() != null) { sb.append("IonText: "); IonWriter prettyWriter = IonTextWriterBuilder.pretty().build(sb); try { prettyWriter.writeValues(IonReaderBuilder.standard().build(valueHolder.getIonText())); } catch (IOException ioe) { sb.append("**Exception while printing this IonText**"); } } sb.append("}"); return sb.toString(); } /** * Returns the string representation of a given {@link GetBlockResult}. * Adapted from the AWS SDK autogenerated {@code toString()} method, with sensitive values un-redacted. * * @param getBlockResult the {@link GetBlockResult} to convert to a String. * @return the String representation of the supplied {@link GetBlockResult}. */ public static String toUnredactedString(GetBlockResult getBlockResult) { StringBuilder sb = new StringBuilder(); sb.append("{"); if (getBlockResult.getBlock() != null) { sb.append("Block: ").append(toUnredactedString(getBlockResult.getBlock())).append(","); } if (getBlockResult.getProof() != null) { sb.append("Proof: ").append(toUnredactedString(getBlockResult.getProof())); } sb.append("}"); return sb.toString(); } /** * Returns the string representation of a given {@link GetDigestResult}. * Adapted from the AWS SDK autogenerated {@code toString()} method, with sensitive values un-redacted. * * @param getDigestResult the {@link GetDigestResult} to convert to a String. * @return the String representation of the supplied {@link GetDigestResult}. */ public static String toUnredactedString(GetDigestResult getDigestResult) { StringBuilder sb = new StringBuilder(); sb.append("{"); if (getDigestResult.getDigest() != null) { sb.append("Digest: ").append(getDigestResult.getDigest()).append(","); } if (getDigestResult.getDigestTipAddress() != null) { sb.append("DigestTipAddress: ").append(toUnredactedString(getDigestResult.getDigestTipAddress())); } sb.append("}"); return sb.toString(); } }
-
Verifier.java
-
-
Use dois arquivos
.java
(GetDigest.java
eGetRevision.java
) para realizar as seguintes etapas:-
Solicite um novo resumo do ledger
vehicle-registration
. -
Solicite uma prova para cada revisão de um documento da tabela
VehicleRegistration
. -
Verifique as revisões usando o resumo e a prova retornados, recalculando o resumo.
O programa
GetDigest.java
contém o código a seguir./* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package software.amazon.qldb.tutorial; import com.amazonaws.services.qldb.AmazonQLDB; import com.amazonaws.services.qldb.model.GetDigestRequest; import com.amazonaws.services.qldb.model.GetDigestResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.qldb.tutorial.qldb.QldbStringUtils; /** * This is an example for retrieving the digest of a particular ledger. * * This code expects that you have AWS credentials setup per: * http://docs.aws.amazon.com/java-sdk/latest/developer-guide/setup-credentials.html */ public final class GetDigest { public static final Logger log = LoggerFactory.getLogger(GetDigest.class); public static AmazonQLDB client = CreateLedger.getClient(); private GetDigest() { } /** * Calls {@link #getDigest(String)} for a ledger. * * @param args * Arbitrary command-line arguments. * @throws Exception if failed to get a ledger digest. */ public static void main(final String... args) throws Exception { try { getDigest(Constants.LEDGER_NAME); } catch (Exception e) { log.error("Unable to get a ledger digest!", e); throw e; } } /** * Get the digest for the specified ledger. * * @param ledgerName * The ledger to get digest from. * @return {@link GetDigestResult}. */ public static GetDigestResult getDigest(final String ledgerName) { log.info("Let's get the current digest of the ledger named {}.", ledgerName); GetDigestRequest request = new GetDigestRequest() .withName(ledgerName); GetDigestResult result = client.getDigest(request); log.info("Success. LedgerDigest: {}.", QldbStringUtils.toUnredactedString(result)); return result; } }
nota
Use o método
getDigest
para solicitar um resumo que cubra a ponta atual do diário em seu ledger. A dica do diário se refere ao último bloco confirmado no momento em que QLDB recebe sua solicitação.O programa
GetRevision.java
contém o código a seguir.nota
Depois que o
getRevision
método retorna uma prova da revisão do documento especificada, esse programa usa um lado do cliente API para verificar essa revisão. Para obter uma visão geral do algoritmo usado por issoAPI, consulteComo usar uma prova para recalcular seu resumo. -
-
Compile e execute o
GetRevision.java
programa para verificar criptograficamente oVehicleRegistration
documento com. VIN1N4AL11D75C109151
Para exportar e validar os dados do diário no ledger vehicle-registration
, vá para Etapa 8: exportar e validar dados do diário em um ledger.