1
$\begingroup$

I've come to use AES/SIC for my purpose as I want to write an encrypted file and read it back with the possibility to seek (I only need to read parts of it and don't want to decrypt the whole file just to read a single part of it).

SIC (using Bouncy Castle) looked promising. I've implemented a stream which is seekable but ended up with a weird issue. I wrote a few values and suddenly at a specific point data become a mess. I investigated into BC and how SIC was implemented. My conclusion: Each time I call Write on the stream, the block number is used and transformed as nonce and internally the counter is increased. In my case I wrote Major and Minor of my version number in single calls, but read it in one go. The one part was okay, the other was a random number.

I now struggle with this, because I need to write the file differently than I would read it. Like writing in intermediate streams to create header files with relative positions in order to seek to the right position later. But since I am writing the header part and the whole body in one go, but read them sequentially field by field, it would not work.

My idea was to introduce a method, which calculates the counter by the current block number. Thus I could write multiple times with the same outcome until the block size has exceeded.

TL;DR: I'm no expert on cryptography, so here's what I want to know: Is it safe to calculate the counter based on the block number in the stream rather than increasing it every write? After all it's more predictable.

Alternatively what would be a good way to go? Is there any encryption algorithm / cipher mode which allows me to write and read in unequal amounts and is still seekable?

$\endgroup$
  • 1
    $\begingroup$ Sounds like a kind of database would be more applicable… as you’ld be encrypting/decrypting individual entries in an easy to manage way, instead of practically replicating the same idea on your own and hitting implementation annoyances like the ones you’re fighting with (which is solvable; but why make it hard on yourself when a DB would be easier). Now, there are scenarios where a DB isn’t an option – but those are borderline cases, which makes me ask: Is there any reason a DB (like SQLite) wouldn’t be an option? Especially, since most DB solutions come with build-in encryption options... $\endgroup$ – e-sushi Jun 15 '18 at 10:24
  • $\begingroup$ You're right... I haven't thought much about databases and kinda forgot about them being able to be encrypted. I guess I'll go this way then. I thought about creating a counter which is generated by the block number, but this probably makes it a lot less safe and probably induces a few other problems. $\endgroup$ – SharpShade Jun 15 '18 at 15:14
  • $\begingroup$ As short appendix: I looked up encryption in databases and ended up with only commerical extensions which are massively expensive (compared to what I need and what I got to do). So I went with encrypting the whole file in one go using CBC. It's just not worth changing all again and a file is still a bit more flexible for my purposes. $\endgroup$ – SharpShade Jun 19 '18 at 6:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.