0

I'm trying to compile and run a tiny sample application, with no luck. The sample application is picked from this response on SF.

This is what I'm doing:

  1. Downloaded a bcprov-jdk15on-159.jar file with BountyCastle library from this page; put it into a sample folder,

  2. Copy-pasted the source from mentioned response; put it into a sample folder,

  3. I now have these files in a folder:

    $ ls -lat
    total 8008
    drwxr-xr-x   4 gmile  staff      136 Jan  6 13:58 .
    -rw-r--r--@  1 gmile  staff  4092400 Jan  6 13:58 bcprov-jdk15on-159.jar
    -rw-r--r--   1 gmile  staff     2302 Jan  6 13:39 PBE.java
    drwxr-xr-x  10 gmile  staff      340 Jan  6 13:38 ..
    
  4. Compile PBE.java into a PBE.class (no issues here):

    $ javac -cp bcprov-jdk15on-159.jar PBE.java
    
  5. Put PBE.class into a .jar file:

    $ jar cvf pbe.jar PBE.class
    added manifest
    adding: PBE.class(in = 2448) (out= 1289)(deflated 47%)
    
  6. Try running the program with dependency included, as seen here, for instance:

    $ java -classpath 'bcprov-jdk15on-159.jar;pbe.jar;' PBE
    Error: Could not find or load main class PBE
    

What am I doing wrong?

oldhomemovie
  • 14,621
  • 13
  • 64
  • 99

1 Answers1

0

Try running (on Windows):

java -cp bcprov-jdk15on-159.jar;pbe.jar PBE

Or on Linux/similar:

java -cp bcprov-jdk15on-159.jar:pbe.jar PBE

If you actually want to see encryption/decryption at work, use same IV and SecretKey for both encryption and decryption, like:

import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class PBE {

    private static final String salt = "A long, but constant phrase that will be used each time as the salt.";
    private static final int iterations = 2000;
    private static final int keyLength = 256;
    private static final SecureRandom random = new SecureRandom();

    public static void main(String [] args) throws Exception {
        Security.insertProviderAt(new BouncyCastleProvider(), 1);

        String passphrase = "The quick brown fox jumped over the lazy brown dog";
        String plaintext = "hello world";

        Cipher cipher = Cipher.getInstance("AES/CTR/NOPADDING");
        SecretKey key = generateKey(passphrase);
    byte[] iv = new byte[cipher.getBlockSize()];
        random.nextBytes(iv);
        byte [] ciphertext = encrypt(key, iv, plaintext);
        String recoveredPlaintext = decrypt(key, iv, ciphertext);

        System.out.println(recoveredPlaintext);
    }

    private static byte [] encrypt(SecretKey key, byte[] iv, String plaintext) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CTR/NOPADDING");
        cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv), random);
        return cipher.doFinal(plaintext.getBytes());
    }

    private static String decrypt(SecretKey key, byte[] iv, byte [] ciphertext) throws Exception {

        Cipher cipher = Cipher.getInstance("AES/CTR/NOPADDING");
        cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv), random);
        return new String(cipher.doFinal(ciphertext));
    }

    private static SecretKey generateKey(String passphrase) throws Exception {
        PBEKeySpec keySpec = new PBEKeySpec(passphrase.toCharArray(), salt.getBytes(), iterations, keyLength);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC");
        return keyFactory.generateSecret(keySpec);
    }

}

niksu
  • 61
  • 4
  • This worked, thank you! Turned out I missed that I should use `:` in Unix (under macOS). Also, had to do this to actually see the program work: https://stackoverflow.com/questions/6481627/java-security-illegal-key-size-or-default-parameters/6481658#6481658 – oldhomemovie Jan 06 '18 at 14:18