1
10package org.jstk.crypt;
11
12import java.util.*;
13import java.security.*;
14import java.io.*;
15import javax.crypto.*;
16import javax.crypto.spec.*;
17
18import org.jstk.*;
19
20public class CryptCommand extends JSTKCommandAdapter{
21 protected static HashMap defaults = new HashMap();
22 static {
23 defaults.put("keystore", "my.keystore");
24 defaults.put("storepass", "changeit");
25 defaults.put("kstype", "JCEKS");
26 defaults.put("alias", "mykey");
27 defaults.put("transform", "DES/CFB8/NoPadding");
28 defaults.put("algorithm", "PBEWithMD5AndDES");
29 }
30 public String briefDescription(){
31 return "encrypt/decrypt using password or key from file or keystore";
32 }
33 public String optionsDescription(){
34 return
35 " -op (enc|dec) : Cryptographic operation: encryption or decryption.\n" +
36 " -infile <infile> : Input data file.\n" +
37 " -outfile <outfile> : Output data file.\n" +
38 " -password <password>: Password for Password Based Encryption(PBE).\n" +
39 " -transform <transform>: Cipher transform(<alg>/<mode>/<padding>).[" +
40 defaults.get("transform") + "]\n" +
41 " -algorithm <algo> : Algo. for password based encryption.[" +
42 defaults.get("algorithm") + "]\n" +
43 " -stream : use CipherInputStream or CipherOutputStream.\n" +
44 " -iv <ivbytes> : initialization vector bytes.\n" +
45 " -keyfile <keyfile> : File having the serialized key.\n" +
46 " -keystore <keystore>: the keystore.[" +
47 defaults.get("keystore") + "]\n" +
48 " -storepass <storepass>: Password for keystore.[" +
49 defaults.get("storepass") + "]\n" +
50 " -kstype <kstype> : the keystore type.[" +
51 defaults.get("kstype") + "]\n" +
52 " -alias <alias> : alias to access the key in the keystore.[" +
53 defaults.get("alias") + "]\n" +
54 " -keypass <keypass> : Password for key in the keystore.\n" +
55 " -provider <provider>: provider name for KeyStore and Cipher.\n" +
56 "\n" +
57 " <<keyinfo>> := (-keyfile <keyfile>|[-keystore <keystore>] [-storepass\n" +
58 " <storepass>] [-kstype <kstype>] [-alias <alias>] [-keypass <keypass>])\n";
59 }
60
61 public String[] useForms(){
62 String[] forms = {
63 "-op (enc|dec) -infile <infile> -outfile <outfile> -password\n" +
64 "\t<password> [-algorithm <algorithm>] [-stream]",
65 "-op (enc|dec) -infile <infile> -outfile <outfile> <<keyinfo>>\n" +
66 "\t[-stream] [-iv <ivbytes>] [-transform <transform>] [-provider <provider>]"
67 };
68 return forms;
69 }
70
71 public String[] sampleUses(){
72 String[] uses = {
73 "-op enc -infile clear.data -outfile enc.data -password changeit",
74 "-op enc -infile clear.data -outfile enc.data -password changeit -stream",
75 "-op dec -infile enc.data -outfile dec.data -keyfile my.secretkey -iv 88888888",
76 "-op enc -infile clear.data -outfile enc.data -transform RSA/ECB/PKCS#1",
77 };
78 return uses;
79 }
80
81 protected Cipher initCipher(JSTKArgs args, int cipherMode) throws Exception {
82 String password = args.get("password");
83 String keyfile = args.get("keyfile");
84 String providerName = args.get("provider");
85 Key key = null;
86 if (password != null){
87 byte[] salt = {
88 (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
89 (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99 };
90 int count = 20;
91 String algorithm = args.get("algorithm");
92 PBEParameterSpec paramSpec = new PBEParameterSpec(salt, count);
93 PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
94 SecretKeyFactory keyFac = SecretKeyFactory.getInstance(algorithm);
95 key = keyFac.generateSecret(keySpec);
96 Cipher cipher = Cipher.getInstance(algorithm);
97 cipher.init(cipherMode, key, paramSpec);
98 return cipher;
99 } else { key = KeyUtil.getKey(args, Key.class);
02 if (cipherMode == Cipher.DECRYPT_MODE && (key instanceof PublicKey)){
04 key = KeyUtil.getKey(args, PrivateKey.class); }
06 }
07
08 String transform = args.get("transform");
09 Cipher cipher;
10 if (providerName != null)
11 cipher = Cipher.getInstance(transform, providerName);
12 else
13 cipher = Cipher.getInstance(transform);
14
15 String ivString = args.get("iv");
16 if (ivString != null){
17 IvParameterSpec ips = new IvParameterSpec(ivString.getBytes());
18 cipher.init(cipherMode, key, ips);
19 } else {
20 cipher.init(cipherMode, key);
21 }
22 return cipher;
23 }
24
25 public Object execute(JSTKArgs args) throws JSTKException{
26 try {
27 args.setDefaults(defaults);
28
29 boolean stream = Boolean.valueOf((String)args.get("stream")).booleanValue();
30
31 int cipherMode;
32 String cryptOp = args.get("op");
33 if (cryptOp == null){
34 return new JSTKResult(null, false, "no cryptographic operation specified");
35 } else if (cryptOp.equals("enc")){
36 cipherMode = Cipher.ENCRYPT_MODE;
37 } else if (cryptOp.equals("dec")){
38 cipherMode = Cipher.DECRYPT_MODE;
39 } else {
40 return new JSTKResult(null, false, "unknown cryptographic operation: " + cryptOp);
41 }
42
43 String infileName = args.get("infile");
44 if (infileName == null)
45 return new JSTKResult(null, false, "no input file specified");
46
47 String outfileName = args.get("outfile");
48 if (outfileName == null)
49 return new JSTKResult(null, false, "no output file specified");
50
51 Cipher cipher = null;
52 try {
53 cipher = initCipher(args, cipherMode);
54 } catch (Exception e){
55 return new JSTKResult(null, false, e.getMessage());
56 }
57
58 FileInputStream fis = new FileInputStream(infileName);
59 FileOutputStream fos = new FileOutputStream(outfileName);
60
61 if (stream){ InputStream is = null;
63 OutputStream os = null;
64
65 if (cipherMode == Cipher.DECRYPT_MODE){
66 is = new CipherInputStream(fis, cipher);
67 os = fos;
68 } else {
69 is = fis;
70 os = new CipherOutputStream(fos, cipher);
71 }
72
73 perfData.updateBegin();
75 byte[] buf = new byte[1024];
76 int n, tot = 0;
77 while ((n = is.read(buf)) > 0){
78 os.write(buf, 0, n);
79 tot += n;
80 }
81 perfData.updateEnd(tot);
82 is.close();
83 os.close();
84 } else {
85 ByteArrayOutputStream baos = new ByteArrayOutputStream();
87 byte[] buf = new byte[1024];
88 int n;
89 while ((n = fis.read(buf)) > 0)
90 baos.write(buf, 0, n);
91 fis.close();
92 byte[] ibuf = baos.toByteArray();
93
94 perfData.updateBegin();
95 byte[] obuf = cipher.doFinal(ibuf);
96 perfData.updateEnd(ibuf.length);
97
98 fos.write(obuf);
99 fos.close();
00 }
01
02 return new JSTKResult(null, true, cryptOp + "rypted file \"" +
03 infileName + "\" to \"" + outfileName + "\"");
04 } catch (Exception exc){
05 throw new JSTKException("CryptCommand.execute() failed", exc);
06 }
07 }
08}