Search in sources :

Example 1 with Nonce

use of com.quorum.tessera.encryption.Nonce in project tessera by ConsenSys.

the class KeyEncryptorImpl method encryptPrivateKey.

@Override
public PrivateKeyData encryptPrivateKey(final PrivateKey privateKey, final char[] password, final ArgonOptions argonOptions) {
    LOGGER.info("Encrypting a private key");
    LOGGER.debug("Encrypting private key {} using password {}", privateKey, password);
    final byte[] salt = new byte[KeyEncryptor.SALTLENGTH];
    this.secureRandom.nextBytes(salt);
    LOGGER.debug("Generated the random salt {}", Arrays.toString(salt));
    final ArgonResult argonResult;
    if (argonOptions == null) {
        argonResult = this.argon2.hash(password, salt);
    } else {
        argonResult = this.argon2.hash(new com.quorum.tessera.argon2.ArgonOptions(argonOptions.getAlgorithm(), argonOptions.getIterations(), argonOptions.getMemory(), argonOptions.getParallelism()), password, salt);
    }
    final Nonce nonce = this.encryptor.randomNonce();
    LOGGER.debug("Generated the random nonce {}", nonce);
    final byte[] encryptedKey = this.encryptor.sealAfterPrecomputation(privateKey.getKeyBytes(), nonce, SharedKey.from(argonResult.getHash()));
    LOGGER.info("Private key encrypted");
    final String snonce = this.encoder.encodeToString(nonce.getNonceBytes());
    final String asalt = this.encoder.encodeToString(salt);
    final String sbox = this.encoder.encodeToString(encryptedKey);
    return new PrivateKeyData(null, snonce, asalt, sbox, new ArgonOptions(argonResult.getOptions().getAlgorithm(), argonResult.getOptions().getIterations(), argonResult.getOptions().getMemory(), argonResult.getOptions().getParallelism()));
}
Also used : Nonce(com.quorum.tessera.encryption.Nonce) ArgonOptions(com.quorum.tessera.config.ArgonOptions) ArgonResult(com.quorum.tessera.argon2.ArgonResult) PrivateKeyData(com.quorum.tessera.config.PrivateKeyData)

Example 2 with Nonce

use of com.quorum.tessera.encryption.Nonce in project tessera by ConsenSys.

the class KeyEncryptorImpl method decryptPrivateKey.

@Override
public PrivateKey decryptPrivateKey(final PrivateKeyData privateKey, final char[] password) {
    LOGGER.info("Decrypting private key");
    LOGGER.debug("Decrypting private key {} using password {}", privateKey.getValue(), password);
    final byte[] salt = this.decoder.decode(privateKey.getAsalt());
    final ArgonResult argonResult = this.argon2.hash(new com.quorum.tessera.argon2.ArgonOptions(privateKey.getArgonOptions().getAlgorithm(), privateKey.getArgonOptions().getIterations(), privateKey.getArgonOptions().getMemory(), privateKey.getArgonOptions().getParallelism()), password, salt);
    final byte[] originalKey = this.encryptor.openAfterPrecomputation(this.decoder.decode(privateKey.getSbox()), new Nonce(this.decoder.decode(privateKey.getSnonce())), SharedKey.from(argonResult.getHash()));
    PrivateKey outcome = PrivateKey.from(originalKey);
    LOGGER.info("Decrypted private key");
    LOGGER.debug("Decrypted private key {}", outcome.encodeToBase64());
    return outcome;
}
Also used : Nonce(com.quorum.tessera.encryption.Nonce) ArgonResult(com.quorum.tessera.argon2.ArgonResult) PrivateKey(com.quorum.tessera.encryption.PrivateKey)

Example 3 with Nonce

use of com.quorum.tessera.encryption.Nonce in project tessera by ConsenSys.

the class EncodedPayloadBuilderTest method encodeForSpecificRecipientWithPsv.

@Test
public void encodeForSpecificRecipientWithPsv() {
    final byte[] sender = new byte[] { 5, 66, -34, 71, -62, 114, 81, 104, 98, -70, -32, -116, 83, -15, -53, 3, 68, 57, -89, 57, 24, 79, -25, 7, 32, -115, -39, 40, 23, -78, -36, 26 };
    final byte[] cipherText = new byte[] { -46, -26, -18, 127, 37, -2, -84, -56, -71, 26, 3, 102, -61, 38, -1, 37, 105, 2, 10, 86, 6, 117, 69, 73, 91, 81, 68, 106, 23, 74, 12, 104, -63, 63, -119, 95, -16, -82, -34, 101, 89, 38, -19, 8, 23, -70, 90, 5, -7, -15, 23, -8, -88, 47, 72, 105, -103, -34, 10, 109, -48, 114, -127, -38, 41, 12, 3, 72, 113, -56, -90, -70, 124, -25, 127, 60, 100, 95, 127, 31, -72, -101, 26, -12, -9, 108, 54, 2, 124, 22, 55, 9, 123, 54, -16, 51, 28, -25, -102, -100, -23, 89, -15, 86, 22, -100, -63, -110, -2, -32, -1, 12, -116, 102, -43, 92, 2, 105, -78, -73, 111, -123, -59, -118, -32, 47, -63, 41, 72, -72, 35, -68, 45, 77, 110, -24, -113, -106, -31, -42, 13, -123, 54, 45, 83, -38, -57, 116, 107, -84, 22, -30, -49, 84, 39, 17, -20, -75, -122, -6, 73, -61, 70, -53, -65, -22, 13, 23, 43, -101, 23, 16, 31, -1, -19, -8, -94, -119, -28, -127, -101, 43, 31, -28, 16, -78, -86, 47, 42, 21, 115, 127, -81, 44, -33, -12, -74, -77, 111, 0, 121, 70, 67, 81, 74, 90, 116, -14, -75, 82, -110, -119, -23, 84, 74, 61, -31, -66, -71, -106, 60, 127, -113, -26, 73, -50, -112, -45, 82, 37, -68, -49, 40, -73, -53, 85, -71, 82, 32, 117, 25, -81, -13, -30, -48, -118, -82, 125, -63, 1, -46, -115, -104, 32, 2, -1, -124, -88, -20, -77, 108, 123, 41, 78, 108, -88, 65, 84, 66, -40, 79, -118, 63, -109, -85, -52, 8, -97, -49, 87, -27, -63, 75, -45, 51, 7, 116, -68, 16, 89, 53, 14, -121, 53, 38, -16, 122, -47, -110, -19, 72, 102, -81, 13, 13, -28, -103, 39, -26, 36, -15, -61, -91, -64, -99, 118, -34, -45, -119, 33, 57, 92, 119, 95, -17, 19, 50, 46, -119, 88, -123, -49, -68, -105, 74, -15, 102, 74, -19, 29, 75, -114, -34, -54, -6, 111, 122, 2, 55, 99, 58, -31, 123, 50, -84, -128, 71, 79, 19, -40, 92, 7, 75, -31, -113, -60, -8, 121, 105, 91, -127, 69, 106, -49, -13, -91, -34 };
    final byte[] nonce = new byte[] { -114, -128, 47, 49, 6, -71, -111, -76, -100, -16, 113, -126, 3, 107, 55, 1, 43, -6, -43, -104, -128, -125, -37, 31 };
    final byte[] recipientNonce = new byte[] { -110, 45, 44, -76, 17, 23, -76, 0, -75, 112, 70, 97, 108, -70, -76, 32, 100, -46, -67, 107, -89, 98, 64, -85 };
    final PublicKey recipient1 = PublicKey.from("recipient".getBytes());
    final PublicKey recipient2 = PublicKey.from("anotherRecipient".getBytes());
    List<PublicKey> recipientList = new ArrayList<>();
    recipientList.add(recipient1);
    recipientList.add(recipient2);
    List<byte[]> recipientBoxes = new ArrayList<>();
    recipientBoxes.add("box".getBytes());
    recipientBoxes.add("anotherBox".getBytes());
    final PrivacyGroup.Id groupId = PrivacyGroup.Id.fromBytes("group".getBytes());
    final EncodedPayload originalPayload = EncodedPayload.Builder.create().withSenderKey(PublicKey.from(sender)).withCipherText(cipherText).withCipherTextNonce(new Nonce(nonce)).withRecipientBoxes(recipientBoxes).withRecipientNonce(new Nonce(recipientNonce)).withRecipientKeys(recipientList).withPrivacyMode(PrivacyMode.PRIVATE_STATE_VALIDATION).withAffectedContractTransactions(singletonMap(new TxHash("test".getBytes()), "test".getBytes())).withExecHash("execHash".getBytes()).withPrivacyGroupId(groupId).build();
    final EncodedPayload payload1 = EncodedPayload.Builder.forRecipient(originalPayload, recipient1).build();
    assertThat(payload1).isNotNull();
    assertThat(payload1.getCipherText()).isEqualTo(originalPayload.getCipherText());
    assertThat(payload1.getSenderKey()).isEqualTo(originalPayload.getSenderKey());
    assertThat(payload1.getRecipientNonce()).isEqualTo(originalPayload.getRecipientNonce());
    assertThat(payload1.getCipherTextNonce()).isEqualTo(originalPayload.getCipherTextNonce());
    assertThat(payload1.getRecipientKeys()).hasSize(2).containsExactly(recipient1, recipient2);
    assertThat(payload1.getRecipientBoxes()).isNotEqualTo(originalPayload.getRecipientBoxes());
    assertThat(payload1.getRecipientBoxes()).hasSize(1).containsExactly(RecipientBox.from("box".getBytes()));
    assertThat(payload1.getPrivacyGroupId()).isPresent().get().isEqualTo(groupId);
    final EncodedPayload payload2 = EncodedPayload.Builder.forRecipient(originalPayload, recipient2).build();
    assertThat(payload2).isNotNull();
    assertThat(payload2.getCipherText()).isEqualTo(originalPayload.getCipherText());
    assertThat(payload2.getSenderKey()).isEqualTo(originalPayload.getSenderKey());
    assertThat(payload2.getRecipientNonce()).isEqualTo(originalPayload.getRecipientNonce());
    assertThat(payload2.getCipherTextNonce()).isEqualTo(originalPayload.getCipherTextNonce());
    assertThat(payload2.getRecipientKeys()).hasSize(2).containsExactly(recipient2, recipient1);
    assertThat(payload2.getRecipientBoxes()).isNotEqualTo(originalPayload.getRecipientBoxes());
    assertThat(payload2.getRecipientBoxes()).hasSize(1).containsExactly(RecipientBox.from("anotherBox".getBytes()));
    assertThat(payload1.getPrivacyGroupId()).isPresent().get().isEqualTo(groupId);
}
Also used : Nonce(com.quorum.tessera.encryption.Nonce) PublicKey(com.quorum.tessera.encryption.PublicKey) Test(org.junit.Test)

Example 4 with Nonce

use of com.quorum.tessera.encryption.Nonce in project tessera by ConsenSys.

the class KeyEncryptorTest method providingArgonOptionsEncryptsKey.

@Test
public void providingArgonOptionsEncryptsKey() {
    final PrivateKey key = PrivateKey.from(new byte[] { 1, 2, 3, 4, 5 });
    final char[] password = "pass".toCharArray();
    final ArgonResult result = new ArgonResult(new com.quorum.tessera.argon2.ArgonOptions("i", 5, 6, 7), new byte[] {}, new byte[] {});
    doReturn(result).when(argon2).hash(any(com.quorum.tessera.argon2.ArgonOptions.class), eq(password), any(byte[].class));
    doReturn(new Nonce(new byte[] {})).when(encryptor).randomNonce();
    doReturn(new byte[] {}).when(encryptor).sealAfterPrecomputation(any(byte[].class), any(Nonce.class), any(SharedKey.class));
    final PrivateKeyData privateKey = this.keyEncryptor.encryptPrivateKey(key, password, new ArgonOptions("i", 5, 6, 7));
    final ArgonOptions aopts = privateKey.getArgonOptions();
    assertThat(privateKey.getSbox()).isNotNull();
    assertThat(privateKey.getAsalt()).isNotNull();
    assertThat(privateKey.getSnonce()).isNotNull();
    assertThat(aopts).isNotNull();
    assertThat(aopts.getIterations()).isNotNull().isEqualTo(5);
    assertThat(aopts.getMemory()).isNotNull().isEqualTo(6);
    assertThat(aopts.getParallelism()).isNotNull().isEqualTo(7);
    assertThat(aopts.getAlgorithm()).isNotNull();
    verify(argon2).hash(any(com.quorum.tessera.argon2.ArgonOptions.class), eq(password), any(byte[].class));
    verify(encryptor).randomNonce();
    verify(encryptor).sealAfterPrecomputation(any(byte[].class), any(Nonce.class), any(SharedKey.class));
}
Also used : Nonce(com.quorum.tessera.encryption.Nonce) ArgonOptions(com.quorum.tessera.config.ArgonOptions) PrivateKey(com.quorum.tessera.encryption.PrivateKey) ArgonResult(com.quorum.tessera.argon2.ArgonResult) PrivateKeyData(com.quorum.tessera.config.PrivateKeyData) SharedKey(com.quorum.tessera.encryption.SharedKey) Test(org.junit.Test)

Example 5 with Nonce

use of com.quorum.tessera.encryption.Nonce in project tessera by ConsenSys.

the class TransactionManagerImpl method receive.

@Override
public ReceiveResponse receive(ReceiveRequest request) {
    final MessageHash hash = request.getTransactionHash();
    LOGGER.info("Lookup transaction {}", hash);
    if (request.isRaw()) {
        final EncryptedRawTransaction encryptedRawTransaction = encryptedRawTransactionDAO.retrieveByHash(hash).orElseThrow(() -> new TransactionNotFoundException("Raw Message with hash " + hash + " was not found"));
        final PublicKey senderKey = PublicKey.from(encryptedRawTransaction.getSender());
        final RawTransaction rawTransaction = new RawTransaction(encryptedRawTransaction.getEncryptedPayload(), encryptedRawTransaction.getEncryptedKey(), new Nonce(encryptedRawTransaction.getNonce()), senderKey);
        final byte[] response = enclave.unencryptRawPayload(rawTransaction);
        return ReceiveResponse.Builder.create().withPrivacyMode(PrivacyMode.STANDARD_PRIVATE).withUnencryptedTransactionData(response).withManagedParties(Set.of(senderKey)).withSender(senderKey).build();
    }
    final EncryptedTransaction encryptedTransaction = encryptedTransactionDAO.retrieveByHash(hash).orElseThrow(() -> new TransactionNotFoundException("Message with hash " + hash + " was not found"));
    final EncodedPayload payload = Optional.of(encryptedTransaction).map(EncryptedTransaction::getPayload).orElseThrow(() -> new IllegalStateException("Unable to decode previously encoded payload"));
    PublicKey recipientKey = request.getRecipient().orElse(searchForRecipientKey(payload).orElseThrow(() -> new RecipientKeyNotFoundException("No suitable recipient keys found to decrypt payload for : " + hash)));
    byte[] unencryptedTransactionData = enclave.unencryptTransaction(payload, recipientKey);
    Set<MessageHash> affectedTransactions = payload.getAffectedContractTransactions().keySet().stream().map(TxHash::getBytes).map(MessageHash::new).collect(Collectors.toSet());
    Set<PublicKey> managedParties = new HashSet<>();
    if (payload.getRecipientKeys().isEmpty()) {
        // legacy tx
        for (RecipientBox box : payload.getRecipientBoxes()) {
            EncodedPayload singleBoxPayload = EncodedPayload.Builder.from(payload).withRecipientBoxes(List.of(box.getData())).build();
            Optional<PublicKey> possibleRecipient = searchForRecipientKey(singleBoxPayload);
            possibleRecipient.ifPresent(managedParties::add);
        }
    } else {
        managedParties = enclave.getPublicKeys().stream().filter(payload.getRecipientKeys()::contains).collect(Collectors.toSet());
    }
    final ReceiveResponse.Builder responseBuilder = ReceiveResponse.Builder.create();
    payload.getPrivacyGroupId().ifPresent(responseBuilder::withPrivacyGroupId);
    return responseBuilder.withUnencryptedTransactionData(unencryptedTransactionData).withPrivacyMode(payload.getPrivacyMode()).withAffectedTransactions(affectedTransactions).withExecHash(payload.getExecHash()).withManagedParties(managedParties).withSender(payload.getSenderKey()).build();
}
Also used : PublicKey(com.quorum.tessera.encryption.PublicKey) TransactionNotFoundException(com.quorum.tessera.transaction.exception.TransactionNotFoundException) Nonce(com.quorum.tessera.encryption.Nonce) RecipientKeyNotFoundException(com.quorum.tessera.transaction.exception.RecipientKeyNotFoundException)

Aggregations

Nonce (com.quorum.tessera.encryption.Nonce)72 Test (org.junit.Test)64 LegacyEncodedPayload (com.quorum.tessera.enclave.encoder.LegacyEncodedPayload)31 PublicKey (com.quorum.tessera.encryption.PublicKey)18 SharedKey (com.quorum.tessera.encryption.SharedKey)6 ArgonResult (com.quorum.tessera.argon2.ArgonResult)4 com.quorum.tessera.enclave (com.quorum.tessera.enclave)4 JerseyTest (org.glassfish.jersey.test.JerseyTest)4 ArgonOptions (com.quorum.tessera.config.ArgonOptions)3 PrivateKeyData (com.quorum.tessera.config.PrivateKeyData)3 MasterKey (com.quorum.tessera.encryption.MasterKey)3 PrivateKey (com.quorum.tessera.encryption.PrivateKey)3 Response (jakarta.ws.rs.core.Response)3 List (java.util.List)3 Optional (java.util.Optional)3 Collectors (java.util.stream.Collectors)3 Service (com.quorum.tessera.service.Service)2 RecipientKeyNotFoundException (com.quorum.tessera.transaction.exception.RecipientKeyNotFoundException)2 TransactionNotFoundException (com.quorum.tessera.transaction.exception.TransactionNotFoundException)2 Json (jakarta.json.Json)2