Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/org/spongycastle/crypto/examples/DESExample.java')
-rw-r--r--core/src/main/java/org/spongycastle/crypto/examples/DESExample.java421
1 files changed, 421 insertions, 0 deletions
diff --git a/core/src/main/java/org/spongycastle/crypto/examples/DESExample.java b/core/src/main/java/org/spongycastle/crypto/examples/DESExample.java
new file mode 100644
index 00000000..f05ffbdf
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/crypto/examples/DESExample.java
@@ -0,0 +1,421 @@
+package org.spongycastle.crypto.examples;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.security.SecureRandom;
+
+import org.spongycastle.crypto.CryptoException;
+import org.spongycastle.crypto.KeyGenerationParameters;
+import org.spongycastle.crypto.engines.DESedeEngine;
+import org.spongycastle.crypto.generators.DESedeKeyGenerator;
+import org.spongycastle.crypto.modes.CBCBlockCipher;
+import org.spongycastle.crypto.paddings.PaddedBufferedBlockCipher;
+import org.spongycastle.crypto.params.DESedeParameters;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.util.encoders.Hex;
+
+/**
+ * DESExample is a simple DES based encryptor/decryptor.
+ * <p>
+ * The program is command line driven, with the input
+ * and output files specified on the command line.
+ * <pre>
+ * java org.spongycastle.crypto.examples.DESExample infile outfile [keyfile]
+ * </pre>
+ * A new key is generated for each encryption, if key is not specified,
+ * then the example will assume encryption is required, and as output
+ * create deskey.dat in the current directory. This key is a hex
+ * encoded byte-stream that is used for the decryption. The output
+ * file is Hex encoded, 60 characters wide text file.
+ * <p>
+ * When encrypting;
+ * <ul>
+ * <li>the infile is expected to be a byte stream (text or binary)
+ * <li>there is no keyfile specified on the input line
+ * </ul>
+ * <p>
+ * When decrypting;
+ * <ul>
+ * <li>the infile is expected to be the 60 character wide base64
+ * encoded file
+ * <li>the keyfile is expected to be a base64 encoded file
+ * </ul>
+ * <p>
+ * This example shows how to use the light-weight API, DES and
+ * the filesystem for message encryption and decryption.
+ *
+ */
+public class DESExample extends Object
+{
+ // Encrypting or decrypting ?
+ private boolean encrypt = true;
+
+ // To hold the initialised DESede cipher
+ private PaddedBufferedBlockCipher cipher = null;
+
+ // The input stream of bytes to be processed for encryption
+ private BufferedInputStream in = null;
+
+ // The output stream of bytes to be procssed
+ private BufferedOutputStream out = null;
+
+ // The key
+ private byte[] key = null;
+
+ /*
+ * start the application
+ */
+ public static void main(String[] args)
+ {
+ boolean encrypt = true;
+ String infile = null;
+ String outfile = null;
+ String keyfile = null;
+
+ if (args.length < 2)
+ {
+ DESExample de = new DESExample();
+ System.err.println("Usage: java "+de.getClass().getName()+
+ " infile outfile [keyfile]");
+ System.exit(1);
+ }
+
+ keyfile = "deskey.dat";
+ infile = args[0];
+ outfile = args[1];
+
+ if (args.length > 2)
+ {
+ encrypt = false;
+ keyfile = args[2];
+ }
+
+ DESExample de = new DESExample(infile, outfile, keyfile, encrypt);
+ de.process();
+ }
+
+ // Default constructor, used for the usage message
+ public DESExample()
+ {
+ }
+
+ /*
+ * Constructor, that takes the arguments appropriate for
+ * processing the command line directives.
+ */
+ public DESExample(
+ String infile,
+ String outfile,
+ String keyfile,
+ boolean encrypt)
+ {
+ /*
+ * First, determine that infile & keyfile exist as appropriate.
+ *
+ * This will also create the BufferedInputStream as required
+ * for reading the input file. All input files are treated
+ * as if they are binary, even if they contain text, it's the
+ * bytes that are encrypted.
+ */
+ this.encrypt = encrypt;
+ try
+ {
+ in = new BufferedInputStream(new FileInputStream(infile));
+ }
+ catch (FileNotFoundException fnf)
+ {
+ System.err.println("Input file not found ["+infile+"]");
+ System.exit(1);
+ }
+
+ try
+ {
+ out = new BufferedOutputStream(new FileOutputStream(outfile));
+ }
+ catch (IOException fnf)
+ {
+ System.err.println("Output file not created ["+outfile+"]");
+ System.exit(1);
+ }
+
+ if (encrypt)
+ {
+ try
+ {
+ /*
+ * The process of creating a new key requires a
+ * number of steps.
+ *
+ * First, create the parameters for the key generator
+ * which are a secure random number generator, and
+ * the length of the key (in bits).
+ */
+ SecureRandom sr = null;
+ try
+ {
+ sr = new SecureRandom();
+ /*
+ * This following call to setSeed() makes the
+ * initialisation of the SecureRandom object
+ * _very_ fast, but not secure AT ALL.
+ *
+ * Remove the line, recreate the class file and
+ * then run DESExample again to see the difference.
+ *
+ * The initialisation of a SecureRandom object
+ * can take 5 or more seconds depending on the
+ * CPU that the program is running on. That can
+ * be annoying during unit testing.
+ * -- jon
+ */
+ sr.setSeed("www.bouncycastle.org".getBytes());
+ }
+ catch (Exception nsa)
+ {
+ System.err.println("Hmmm, no SHA1PRNG, you need the "+
+ "Sun implementation");
+ System.exit(1);
+ }
+ KeyGenerationParameters kgp = new KeyGenerationParameters(
+ sr,
+ DESedeParameters.DES_EDE_KEY_LENGTH*8);
+
+ /*
+ * Second, initialise the key generator with the parameters
+ */
+ DESedeKeyGenerator kg = new DESedeKeyGenerator();
+ kg.init(kgp);
+
+ /*
+ * Third, and finally, generate the key
+ */
+ key = kg.generateKey();
+
+ /*
+ * We can now output the key to the file, but first
+ * hex encode the key so that we can have a look
+ * at it with a text editor if we so desire
+ */
+ BufferedOutputStream keystream =
+ new BufferedOutputStream(new FileOutputStream(keyfile));
+ byte[] keyhex = Hex.encode(key);
+ keystream.write(keyhex, 0, keyhex.length);
+ keystream.flush();
+ keystream.close();
+ }
+ catch (IOException createKey)
+ {
+ System.err.println("Could not decryption create key file "+
+ "["+keyfile+"]");
+ System.exit(1);
+ }
+ }
+ else
+ {
+ try
+ {
+ // read the key, and decode from hex encoding
+ BufferedInputStream keystream =
+ new BufferedInputStream(new FileInputStream(keyfile));
+ int len = keystream.available();
+ byte[] keyhex = new byte[len];
+ keystream.read(keyhex, 0, len);
+ key = Hex.decode(keyhex);
+ }
+ catch (IOException ioe)
+ {
+ System.err.println("Decryption key file not found, "+
+ "or not valid ["+keyfile+"]");
+ System.exit(1);
+ }
+ }
+ }
+
+ private void process()
+ {
+ /*
+ * Setup the DESede cipher engine, create a PaddedBufferedBlockCipher
+ * in CBC mode.
+ */
+ cipher = new PaddedBufferedBlockCipher(
+ new CBCBlockCipher(new DESedeEngine()));
+
+ /*
+ * The input and output streams are currently set up
+ * appropriately, and the key bytes are ready to be
+ * used.
+ *
+ */
+
+ if (encrypt)
+ {
+ performEncrypt(key);
+ }
+ else
+ {
+ performDecrypt(key);
+ }
+
+ // after processing clean up the files
+ try
+ {
+ in.close();
+ out.flush();
+ out.close();
+ }
+ catch (IOException closing)
+ {
+
+ }
+ }
+
+ /*
+ * This method performs all the encryption and writes
+ * the cipher text to the buffered output stream created
+ * previously.
+ */
+ private void performEncrypt(byte[] key)
+ {
+ // initialise the cipher with the key bytes, for encryption
+ cipher.init(true, new KeyParameter(key));
+
+ /*
+ * Create some temporary byte arrays for use in
+ * encryption, make them a reasonable size so that
+ * we don't spend forever reading small chunks from
+ * a file.
+ *
+ * There is no particular reason for using getBlockSize()
+ * to determine the size of the input chunk. It just
+ * was a convenient number for the example.
+ */
+ // int inBlockSize = cipher.getBlockSize() * 5;
+ int inBlockSize = 47;
+ int outBlockSize = cipher.getOutputSize(inBlockSize);
+
+ byte[] inblock = new byte[inBlockSize];
+ byte[] outblock = new byte[outBlockSize];
+
+ /*
+ * now, read the file, and output the chunks
+ */
+ try
+ {
+ int inL;
+ int outL;
+ byte[] rv = null;
+ while ((inL=in.read(inblock, 0, inBlockSize)) > 0)
+ {
+ outL = cipher.processBytes(inblock, 0, inL, outblock, 0);
+ /*
+ * Before we write anything out, we need to make sure
+ * that we've got something to write out.
+ */
+ if (outL > 0)
+ {
+ rv = Hex.encode(outblock, 0, outL);
+ out.write(rv, 0, rv.length);
+ out.write('\n');
+ }
+ }
+
+ try
+ {
+ /*
+ * Now, process the bytes that are still buffered
+ * within the cipher.
+ */
+ outL = cipher.doFinal(outblock, 0);
+ if (outL > 0)
+ {
+ rv = Hex.encode(outblock, 0, outL);
+ out.write(rv, 0, rv.length);
+ out.write('\n');
+ }
+ }
+ catch (CryptoException ce)
+ {
+
+ }
+ }
+ catch (IOException ioeread)
+ {
+ ioeread.printStackTrace();
+ }
+ }
+
+ /*
+ * This method performs all the decryption and writes
+ * the plain text to the buffered output stream created
+ * previously.
+ */
+ private void performDecrypt(byte[] key)
+ {
+ // initialise the cipher for decryption
+ cipher.init(false, new KeyParameter(key));
+
+ /*
+ * As the decryption is from our preformatted file,
+ * and we know that it's a hex encoded format, then
+ * we wrap the InputStream with a BufferedReader
+ * so that we can read it easily.
+ */
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
+
+ /*
+ * now, read the file, and output the chunks
+ */
+ try
+ {
+ int outL;
+ byte[] inblock = null;
+ byte[] outblock = null;
+ String rv = null;
+ while ((rv = br.readLine()) != null)
+ {
+ inblock = Hex.decode(rv);
+ outblock = new byte[cipher.getOutputSize(inblock.length)];
+
+ outL = cipher.processBytes(inblock, 0, inblock.length,
+ outblock, 0);
+ /*
+ * Before we write anything out, we need to make sure
+ * that we've got something to write out.
+ */
+ if (outL > 0)
+ {
+ out.write(outblock, 0, outL);
+ }
+ }
+
+ try
+ {
+ /*
+ * Now, process the bytes that are still buffered
+ * within the cipher.
+ */
+ outL = cipher.doFinal(outblock, 0);
+ if (outL > 0)
+ {
+ out.write(outblock, 0, outL);
+ }
+ }
+ catch (CryptoException ce)
+ {
+
+ }
+ }
+ catch (IOException ioeread)
+ {
+ ioeread.printStackTrace();
+ }
+ }
+
+}
+