Let's make a class to use a 64 bit block cipher in CBC (cipher block chaining) mode! We'll use ciphertext stealing for our padding strategy. And we'll create simple helper methods to encrypt and decrypt parts of text files easily.
You may be interested in browsing the wiki pages for block ciphers, block cipher modes, CBC with ciphertext stealing, and perhaps Blowfish.
A bunch of support code is already written and tested! The Blowfish class implements the Blowfish algorithm. You use it by calling the constructor with an array of bytes for the encryption key. Then you will want to encrypt and decrypt 64 bit blocks (longs). It implements the BlockCipher64 interface with it's encrypt and decrypt methods. BlockCipher64 also contains two static helpers for translating byte arrays to longs and vice versa. The BlowfishTestVectors helped me verify that our implementation was consistent with the reference implementation. CBCEncryption needs some work, but contains a lot of the bits and pieces you'll need.
- Read through
CBCEncryption, it'll save you time in the long run to know what methods are there and what they do. - A few methods need fixin':
- Now try out some examples to get an idea of what's happening
- Work out how we should
decryptan encrypted ciphertext. Use the comments and the ciphertext stealing page. Draw an example (perhaps the two samples), figure out where the bytes ought to go. - See if your
decryptdoes what you thought it should do in your example. See that it reverses the effect ofencrypt. - Build
decryptFileBlowfish, it's straight forward. It's mostly the same parts used inencryptFileBlowfish, but in reverse (of course). - Play with it!
u0xee $ java CBCEncryption partialBlockSample
plaintext = [97, 98, 99, 100, 101, 102, 103, 104, 73, 74, 75, 76, 77, 78, 79, 80, 49, 50]
firstBlock = [97, 98, 99, 100, 101, 102, 103, 104]
secondBlock = [73, 74, 75, 76, 77, 78, 79, 80]
firstBlock ^ secondBlock = [40, 40, 40, 40, 40, 40, 40, 56]
ciphertext = [97, 98, 99, 100, 101, 102, 103, 104, 25, 26, 40, 40, 40, 40, 40, 56, 40, 40]
decrypted = [97, 98, 99, 100, 101, 102, 103, 104, 73, 74, 75, 76, 77, 78, 79, 80, 49, 50]
bytesToString(decrypted) = abcdefghIJKLMNOP12u0xee $ java CBCEncryption evenBlockSample
plaintext = [97, 98, 99, 100, 101, 102, 103, 104, 73, 74, 75, 76, 77, 78, 79, 80]
firstBlock = [97, 98, 99, 100, 101, 102, 103, 104]
secondBlock = [73, 74, 75, 76, 77, 78, 79, 80]
firstBlock ^ secondBlock = [40, 40, 40, 40, 40, 40, 40, 56]
ciphertext = [40, 40, 40, 40, 40, 40, 40, 56, 97, 98, 99, 100, 101, 102, 103, 104]
decrypted = [97, 98, 99, 100, 101, 102, 103, 104, 73, 74, 75, 76, 77, 78, 79, 80]
bytesToString(decrypted) = abcdefghIJKLMNOPu0xee $ java CBCEncryption fileSample 'secret key!!' ../resources/original.txt
u0xee $ diff -u ../resources/original.txt ../resources/original.txt.secret.txt
--- ../resources/original.txt 2016-07-27 14:50:56.000000000 -0600
+++ ../resources/original.txt.secret.txt 2016-07-27 21:30:43.000000000 -0600
@@ -1,8 +1,8 @@
Hello Bob,
I wanted to share a message with you:
-<<<
-My favorite flavor is hazelnut!
+<<< Base64 encoding of 16 round Blowfish in CBC mode with ciphertext stealing. IV:248631d45c56e53d
+6st1XVWoewNKRE4NYCBhBUHD7i0w4w8mZFsV2r67tA==
>>>
Wasn't that a great secret?
@@ -10,9 +10,8 @@
Alice
P.S.
-<<<
-These letters have been a great distraction.
-I know you are always there to hear what I have to say.
-Write again soon, but not too soon.
-Thanks
+<<< Base64 encoding of 16 round Blowfish in CBC mode with ciphertext stealing. IV:506d10c226ea275b
+2+jlN4WzO3uUK3zOf585bxjs7q3i0ReeM7Mb0HV7GrgS3OCVPvnT7BCgpXBNwg2f
+7UseXZCoZBYmdwxuCdYJ+TEH8y85RmJQeg4O0B8I++YgkteD8P43VSpcDxfojON8
+TDougD/8e5uoTH3o7Jro9lODnrtbw7XEtG7UMFSY40uFRNVQjOsFWWl8exEdYnc=
>>>
u0xee $ diff -u ../resources/original.txt ../resources/original.txt.secret.txt.opened.txt
u0xee $