First of all, I'm going to assume that this is for educational purposes only. If not, see Don't roll your own and Don't be a Dave.
What you have is basically a variant of the caesar cipher (well, more or less). You take each character of the input and add a fixed amount (the key) to it. Some parts of the output also depend on previous calculations, but not all of them (not at the beginning or at the end).
I haven't yet looked into it in-depth, but the first problems I saw are:
- your key size is incredibly small, as it is limited by the size of
int
. This makes brute force attacks simplesimple[*]. - a chosen plaintext attack is possible to gain the key: If the message that is to be encrypted is the same length as
BYTES_PER_INT
, the key can be computed:int key = readInt(ciphertext, ciphertext.length - BYTES_PER_INT) - readInt(plaintext, plaintext.length - BYTES_PER_INT)
. This is because in that case, the algorithm is indeed just a simple ceasar cipher. - for small keys, a known plaintext attack is possible. An attacker could get the key if they have access to a plaintext and a matching cipher, as they can just calculate the offset of the first value of the ciphertext and the plaintext, and thus gain the key (actually, I think that a known plaintext attack should be possible regardless of key length, but for some reason I can't think of a way right now).
- as you are not padding, the last X values of the ciphertext are always equal to the plaintext.
So no, this would not be secure. And there may very likely be more severe problems than the ones I described. But even those are enough to show that there are problems in the algorithm.
[*]
Also, is it easy to crack that cipher if the hacker, say, knows that the file encrypted is a source code file in some particular language?
Yes, it will be simple for an attacker to know when they used a correct key.
I'm assuming that you would encode a message like this: message.getBytes()
, and then get it back from a cipher via new String(cipher)
. You can test this and see that a wrong key will give you a lot of non-ascii characters, making a distinction between correct and incorrect decryption easy.
Misc
- A cipher key doesn't really exist. Just
key
is fine. - your JavaDoc comments are quite nice. They are well formatted and contain all the information needed to understand what a method does.