Jackson Json Crypto with temporal workflow - Decryption of data while retrieval not happening

147 views Asked by At

I am using temporal workflows to manage states and currently data is being saved as plain text which i want to save the data in encrypted format.

For that, I am using Jackson Json Crypto module for encryption. Encryption is working fine and data is getting saved in encrypted form but while deserialising, data is not getting back converted to actual data. I believe @Encrypt annotation which is used and defined on the field is not getting triggered. I have download the decompiled library code as well and tried debugging, where i found deserialising module constructors are getting called initially but later the @Override deserialise function is not getting triggered and the encrypted json output is getting returned as it is and getting mapped to the field.

Anyone any idea, how annotation works while serialising, deserialising? Also, @Encrypt annotation will work first or object mapper will map the data to pojo?

Thanks in advance

Code snippets

//Configuration and registering crypto module in object mapper

EncryptionService encryptionService = new EncryptionService(jacksonObjectMapper, new PasswordCryptoContext("Password1")); jacksonObjectMapper.registerModule(new CryptoModule().addEncryptionService(encryptionService));

//Encrypt annotation on field

@JsonProperty("order_id") @Encrypt private String orderId;

// Encrypted Data Output

"order_id": {        "salt": "Bf53VhtWMF95Cp7wLb8EJ9tRfIc=",        "iv": "X83bkmfrvHk4SGCTJ+zx/g==",        "value": "L8VEVKkEp0j7KG0cG2IFjHdNmMKcIxnLIb0+fiNqnDr2AXRrFgwJaaR6E8f5n7DI"      }

While deserialising

//Expecting

"order_id":"abcd" // actual string

//Output

"order_id": {        "salt": "Bf53VhtWMF95Cp7wLb8EJ9tRfIc=",        "iv": "X83bkmfrvHk4SGCTJ+zx/g==",        "value": "L8VEVKkEp0j7KG0cG2IFjHdNmMKcIxnLIb0+fiNqnDr2AXRrFgwJaaR6E8f5n7DI"      }
1

There are 1 answers

4
James On

I don't think your issue is related Jackson's annotation. More likely related to the way you register your Jackson ObjectMapper to your Temporal Client's PayloadConverter.

I suggest you get a look at this sample from the Temporal's Java SDK Samples official repository, which does exactly what you are trying to do.

The important thing to observe in that sample is:

  1. The Jackson's ObjectMapper must be wrapped into a JacksonJsonPayloadConverter object, like this:
    PayloadConverter encryptingPayloadConverter =
            new JacksonJsonPayloadConverter(objectMapper);
  1. A new DataConverter must be created, that includes your custom PayloadConverter:
    DataConverter customDataConverter =
            DefaultDataConverter.newDefaultInstance()
                .withPayloadConverterOverrides(encryptingPayloadConverter)
  1. Your custom DataConverter must be attached to your Temporal Client:
    WorkflowClient.newInstance(
            service,
            WorkflowClientOptions.newBuilder()
                .setDataConverter(customDataConverter)
                .build());

Make sure to do this for all Temporal Clients that will manipulate that type of payloads (eg. client code, Workflow workers, and Activity workers).

Also, notice that even though using the Jackson Json Crypto module might be a bit easier to start with, it is alternatively possible to implement encryption using a PayloadCodec (see this sample). PayloadCodec will turn out easier to use in cross-language scenarios, and allow encoding Temporal Failure' messages and stack traces.