Reputation: 101
I am working on a Stream Cipher program in Java which should take three arguments from the shell: a file with a key, a file for input, and a file for output. The key should then serve as the seed which should generate a pseudo-random number which should be "XOR:ed" with the plaintext in the input file.
I have managed to write the code for reading a file but I do not know how I am supposed to write the code for taking the key as the seed and thus generate a pseudo-random number as explained above. Could someone help me?
public static void main(String[] args) throws IOException {
File key = null;
File input = null;
File output = null;
if (0 < args.length) {
key = new File(args[0])
input = new File(args[1]);
output = new File(args[2]);
}
//more stuff
//a function that takes the seed from the key file and should generate a pseudo-random number
int prng (long seed) {
Random random = new Random ();
int bound = 256;
int number = random.nextInt(bound);
return number;
}
Upvotes: 0
Views: 841
Reputation: 15693
You need a stream of (pseudo-)random bytes using java.util.Random
. Start by reading the seed/key from the user and use that to initialise your instance of the Random class.
long seedKey = getUserInput();
Random myRandom = new Random(seedKey);
Do that once only at the start of your code.
Next, you need to process your input. If you are happy with using streams, then you could use Random.ints()
or Random.longs()
to generate the random keystream. Alternatively, break up the input file into chunks and use Random.bytes(myAry)
to get enough bytes to XOR with whatever size chunk you are using.
Unless you are using one byte chunks you will need to deal with any part-chunk left at the end of the input.
Output from the XOR will be raw bytes, not text. If you need text output then convert to Base64 using java.util.Base64
so you get something printable, which raw encrypted bytes are not.
Upvotes: 0
Reputation: 94058
Pseudo-random as described by the assignment doesn't mean that you need to use a random number generator. The key stream created by the stream cipher is pseudo random (to an adversary) because it is generated from a key that they don't know. So you should not be using either Random
or SecureRandom
or similar. Instead, you should be using Cipher
.
Basically there are two ways that you can implement CTR mode. First, you can create a stream of 16-byte unique values and encrypt them using AES in ECB mode (or use the block cipher directly, but that's not available in Java). Then you get 16 bytes of key stream in return, which you can buffer and use to XOR with the plaintext.
You can also cheat and use AES/CTR/NoPadding
. Then to get to the key stream you update with bytes all set to zero. Because XOR with zero is the identity function, you'll get the key stream back. This you can in turn XOR with the actual plaintext to get the ciphertext. As this is for practice, you probably learn more if you implement the earlier method though.
Upvotes: 0