Closed kellymclaughlin closed 4 years ago
All tests passed:
[INFO] Reactor Summary:
[INFO]
[INFO] java-manta 3.4.2-SNAPSHOT .......................... SUCCESS [ 5.250 s]
[INFO] java-manta-client-unshaded ......................... SUCCESS [06:48 min]
[INFO] java-manta-client .................................. SUCCESS [ 8.782 s]
[INFO] java-manta-client-kryo-serialization ............... SUCCESS [ 39.553 s]
[INFO] java-manta-cli ..................................... SUCCESS [02:16 min]
[INFO] java-manta-it ...................................... SUCCESS [19:45 min]
[INFO] java-manta-benchmark ............................... SUCCESS [02:12 min]
[INFO] java-manta-examples 3.4.2-SNAPSHOT ................. SUCCESS [ 0.528 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 31:57 min
[INFO] Finished at: 2020-03-20T15:21:01-07:00
[INFO] ------------------------------------------------------------------------
The heart of this problem is that we need a way when using AES/CTR mode to increment the counter that's used along with the nonce or initialization vector (IV) as input to the decryption process based on the block that the bytes returned from the Range header request belong to. Presently, our solution to that is the calls to Cipher.update, but this is an expensive method when really all we need is to increment a counter to reflect the current block being decrypted. So instead what we can do is to take the IV and increment that value manually (I could not find any built-in Java API for this purpose) and then we can proceed to decrypt the block just like before. Calculating this block-targeted IV value is very cheap compared to the update calls.
I created a test program that riffs on the Range header example already in the repo. It uploads an object to Manta and then downloads 1024 bytes chunks from the beggining, middle, and end of the object and reports the time it took and if the downloaded data matched what we expected. Here is the full code I used:
Here is a run of the test program without the changes for this PR (i.e. It is using the
Cipher.update
method to increment the AES/CTR counter):As has been reported the time complete the request for each file chunk increases as the offset into the object increases.
Now here is a run of the program with the changes from this PR:
The reported times for each chunk request are now within the same order of magnitude which is exactly what we want while the data for each chunk still matches our expected data indicating successful decryption.