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
decrypt
an 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
decrypt
does 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) = abcdefghIJKLMNOP12
u0xee $ 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) = abcdefghIJKLMNOP
u0xee $ 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 $