Sunday, October 21, 2018

Encrypting files with the ability to quickly change the password

NOTE: This is just a proof of concept and this exact implementation should NOT be used in production. There are other elements in security omitted from this article, so this is strictly for POC and educational purposes.

While working the other day, I was suggested to a guest by a co-worker. The question revolved around cryptography. His scenario is say we decided to encrypt a large set of data maybe 2TB in size with a particular key (lets use "cat" for this example). The issue was that if you wanted to change the password you would essentially have to first decrypt it to obtain the original data, then take that and encrypt it with a new password (lets say "dog"). He wanted a method where he wouldn't have to re-encrypt his data while still being able to change the password. He said he went to the genius bar at apple and they told him it is impossible. I will present a possible solution to the problem. The solution allows for a user to encrypt and decrypt with a password, and also have the ability to quickly change that password without having to first decrypt and re-encrypt.

If you are to imagine encrypting a file. What you typically need is (in this case AES128) a 128bit key, and a 128bit IV. Typically this Key/IV can be generated with a hash algorithm (in this case like SHA256) which produces the necessary size key/IV. An adversary would need to know what "Password" you used to produce the same hash that it did which was used to encrypt the data. The link between the "Password" and the "Key/IV" is a Hash function. That "Key/IV is never stored anywhere either, it is just a result of the hash function only when needed and when the original "Password" was the input. So how can we make it so that we have the ability force another "Password" to produce the same "Key/IV" and the old one produce a completely different/wrong "Key/IV"? The simplest solution is XOR.

The scheme would look like this:
[Encrypt]
1) Choose desired "Password".
2) Hash the "Password" in step 1.
3) Generate cryptographic random bytes (length of "Key/IV").
4) Encrypt Data with random bytes from step 3).
5) XOR the random bytes in step 3 with the "Password" hash in step 2 to get a bit mask.
6) Prepend or Append or store the bit mask in step 5.

[Decrypt]
1) Enter "Password".
2) Hash the "Password" in step 1.
3) Read bit mask in [Encrypt]Step 5 where ever it was stored.
4) Xor bit mask from step 3 with "Password" hash in step 2 to get the "Key/IV".
5) Decrypt Data with "Key/IV" from step 4.

[Change Password]
1) Enter current "Password".
2) Hash the "Password" in step 1.
3) Read bit mask in [Encrypt]Step 5 where ever it was stored.
4) Xor bit mask from step 3 with "Password" hash in step 2 to get the "Key/IV".
5) Enter the new "Password".
6) Hash the "Password" in step 5.
7) Xor "Password" hash in step 6 with "Key/IV" in step 4 to get a new bit mask.
8) Replace where ever the old bit mask was stored with the new bit mask in step 7.

Now for some code and proof of concept:

First lets get some AES code going. One which takes a byte array to use as the "Key/IV".


Now we need a cryptographic random number generator, a way to XOR two byte arrays, and finally a SHA256 hash function.




Next up lets implement the Encryption, Decryption, and the Change methods. I will be saving the bit mask as a file called ".bm" along side the encrypted file which will be called ".en".


Here is the test code in order:


Initially we start off with this test image/file.


Then we run the FlexEncrypt method to get a new folder with the encrypted file and its bitmask inside:


Here are those two files inside:


Here is a look at those two files in a hex editor:


Now we run the FlexChange method to change the password from "cat" to "dog" and in the Hex editor we can see that the encrypted file stays the same but the bitmask has changed.


Finally we decrypt with the password "dog" and we get this decrypt folder with hopefully the original test image we started off with:


And indeed we do:

Thursday, October 11, 2018

New MicroSecond Timer

So a while ago, I stitched together a little Timer class which does sub millisecond timings because windows isn't a real-time operating system and the Framework doesn't out of the box provide any timers capable of such for my game engine. It was a rough stitch to say the least but I've gotten around to looking it over and making it a little bit cleaner etc. I also commented as much as possible to explain what the code is/does.