Loading…

Kryptel/Java

Parcel Creation Example

Creating a Silver Key Parcel

This example demonstrates the use of ISilverKeyParcel and ISilverKeyStream interfaces for creating a Silver Key parcel.

In order to reduce unrelated code as much as possible, this example uses a hard-wired password and hard-wired file paths. A real-life program must never use a hard-wired password as that makes encryption pretty useless.

import static com.kryptel.bslx.Targets.GetTargetName;
import static com.kryptel.bslx.Targets.TARGET_ASK_USER;
import static com.kryptel.Guids.CID_CIPHER_AES;
import static com.kryptel.Guids.CID_SILVER_KEY;
import static com.kryptel.Guids.IID_ISilverKeyParcel;

import java.util.UUID;

import com.kryptel.bslx.BooleanFlag;
import com.kryptel.IKeyCallback;
import com.kryptel.IKryptelComponent;
import com.kryptel.IProgressCallback;
import com.kryptel.KeyIdent;
import com.kryptel.KeyRecord;
import com.kryptel.Loader;
import com.kryptel.ProgressCallback;
import com.kryptel.silver_key.ISilverKeyParcel;
import com.kryptel.silver_key.ISilverKeyStream;

First we need to implement the callback interfaces. The most important one for an encryption program is IKeyCallback. We use a pre-defined password to make the implementing class simpler.

class KeyCallback implements IKeyCallback {
  private static final String PREDEFINED_PASSWORD = "qwerty";

  public KeyRecord Callback(Object arg,
                            String prompt,
                            int allowed,
                            UUID expected) throws Exception {
    assert ((allowed & IKeyCallback.PASSWORD) != 0);    // Password is allowed
    KeyRecord kr = new KeyRecord();
    kr.keyMaterial = KeyIdent.IDENT_PASSWORD;
    kr.password = PREDEFINED_PASSWORD;
    return kr;
  }
}

The implementation of the key callback is pretty straightforward – we just return the predefined password in KeyRecord.

The progress callback implementation requires a bit more programming effort. We are using ProgressCallback helper class, which implements IProgressCallback. Instead we need to implement ProgressCallback.IProgressDialog, which is more suitable for dialog boxes.

class Progress implements ProgressCallback.IProgressDialog {
  public void CreateProgress(Object arg,
    String strTitle,
    boolean totalBar,
    BooleanFlag abortRequested) {
  }

  public void SetProgressMessage(Object arg, String strMessage) {
    System.out.print(strMessage);
  }

  public void SetProgressStep(Object arg, int fileStep, int totalStep) {
    if (fileStep == IProgressCallback.PROGRESS_STEPS)
      System.out.println("  Done!");
  }

  public void DismissProgress(Object arg) { }
}

We are not going to create a dialog box though. Our simple implementation prints the file name to be encrypted and the message Done when it is fully processed (i.e. when the progress step reaches ProgressCallback.PROGRESS_STEPS).

Now we are ready to write the main encryption code:

public class SkTest {

  private static final String PARCEL_TITLE = "Test Parcel";

  public static void main(String[] args) {
    try {
      IKryptelComponent skComp = (IKryptelComponent)Loader.CreateComponent(CID_SILVER_KEY);
      ISilverKeyParcel sk = (ISilverKeyParcel)skComp.GetInterface(IID_ISilverKeyParcel);

      sk.SetParcelTitle(PARCEL_TITLE);
      sk.AttachDescription("This is a test Silver key parcel containing a few files,\n"
                         + "a directory tree, and a couple of encrypted messages.");

      String destPath = GetTargetName(TARGET_ASK_USER) + "|Decrypted/";

      ISilverKeyStream stream = sk.Create(
                  "C:\\SkTest\\Parcel.sk",
                  ISilverKeyParcel.PARCEL_TYPE.STUBLESS,
                  Loader.CreateComponent(CID_CIPHER_AES),
                  null,
                  new KeyCallback(),
                  new ProgressCallback(PARCEL_TITLE, new Progress(), null));

      stream.AddMessage("Processing a couple of files");
      stream.StoreFile(destPath + "Targets.docx", "C:\\SkTest\\Targets.docx");
      stream.StoreFile(destPath + "Capture.png", "C:\\SkTest\\Capture.png");
      stream.AddMessage("Processing a directory subtree");
      stream.StoreTree(destPath + "Subdir", "C:\\SkTest\\Subdir");

      sk.Close();
    }
    catch (Exception ex) {
      System.out.println(ex.toString());
    }
  }
}

Main function step by step

Let's see what this program does, step by step.

IKryptelComponent skComp = (IKryptelComponent)Loader.CreateComponent(CID_SILVER_KEY);
ISilverKeyParcel sk = (ISilverKeyParcel)skComp.GetInterface(IID_ISilverKeyParcel);

First, it instantiates the Silver Key engine and obtains ISilverKeyParcel interface.

sk.SetParcelTitle(PARCEL_TITLE);
sk.AttachDescription("This is a test Silver key parcel containing a few files,\n"
                 + "a directory tree, and a couple of encrypted messages.");

These commands optional. The first call sets a custom parcel title instead of the default Silver Key parcel. The second function attaches a non-encrypted parcel description, which will be shown before decryption start.

String destPath = GetTargetName(TARGET_ASK_USER) + "|Decrypted/";

Assigns the destination path, i.e. the path where the parcel items will be decrypted. The decryptor will ask the user to which directory the items should be decrypted, and will decrypt them to the Decrypted subdirectory of that directory. See Targets class for a discussion of targets.

Note the trailing slash character. You can use both slash and backslash separators – the decryptor will replace them with separators appropriate for the target system.

ISilverKeyStream stream = sk.Create(
          "C:\\SkTest\\Parcel.sk",
          ISilverKeyParcel.PARCEL_TYPE.STUBLESS,
          Loader.CreateComponent(CID_CIPHER_AES),
          null,
          new KeyCallback(),
          new ProgressCallback(PARCEL_TITLE, new Progress(), null));

Creates the parcel and returns ISilverKeyStream

stream.AddMessage("Processing a couple of files");
stream.StoreFile(destPath + "Targets.docx", "C:\\SkTest\\Targets.docx");
stream.StoreFile(destPath + "Capture.png", "C:\\SkTest\\Capture.png");
stream.AddMessage("Processing a directory subtree");
stream.StoreTree(destPath + "Subdir", "C:\\SkTest\\Subdir");

These five commands form the parcel script. They add an encrypted message, two files, another encrypted message, and a subfolder (which contains two text files).

Note that the item names must be specified in both the source and the destination paths.

sk.Close();

And the last call finalizes the parcel and finishes processing.

If we run this program, we will see the following output generated by our Progress callback class:

Targets.docx  Done!
Capture.png  Done!
  Done!
urllist.txt  Done!

It is interesting to note that one of the smaller files (specifically Subdir\Titles.txt) was skipped by the progress tracking code. This is a normal situation – the progress bar code is optimized and may skip small files that don't cause the position of the progress bar to change.

We can use Parcel Analyzer to peek inside our just created parcel:

Using Parcel Analyzer to view parcel contents

The Analyzer shows (and lets selectively execute) the script commands that we created with calls to ISilverKeyStream interface (the StoreTree call had been unfolded).