package groomiac.crocodesktop; import groomiac.encryptor.PBKDF2; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.Arrays; import java.util.Properties; import java.util.Random; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import javax.swing.JOptionPane; import org.apache.commons.codec.binary.Base64; public class Base { final static String aes = "AES"; final static String ecb = "AES/ECB/NoPadding"; final static String cbc = "AES/CBC/PKCS5Padding"; final static String hmac = "HmacSHA256"; final static String file_secret = "secret.conf"; final static String appname = "CrocodileNote"; final static String t_cancel = "Cancel"; final static String t_ok = "Ok"; final static String t_okay = "Okay"; final static String t_yes = "Yes"; final static String t_no = "No"; final static String t_return = "Return"; protected static byte[] tmp_esk; protected static Cipher kcipher; protected static Mac ivMac; static void deinit(){ if(Log.DEBUG) System.out.println("DEINIT"); secretpropFile = null; keyprops = null; keyprops = new Properties(); } static void logout(){ if(Log.DEBUG) System.out.println("LOGOUT"); if(tmp_esk != null) new Random(System.nanoTime()).nextBytes(tmp_esk); try { if(kcipher != null) kcipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(tmp_esk, aes)); } catch (Exception e) { e.printStackTrace(); } } static void loadSecrets() { if(secretpropFile.exists() && secretpropFile.isFile()){ try { FileInputStream fis = new FileInputStream(secretpropFile); keyprops.load(fis); fis.close(); } catch (Exception e) { e.printStackTrace(); } } } //Crypto static boolean loaded(){ return tmp_esk != null; } static boolean loadpw(String pw){ if(loaded()) return true; try { //Check key material byte[] tmp_ce, tmp_cd, tmp_ke, s; int it = getSecretInt(_P.i); tmp_ce = getSecretBytes(_P.ce); tmp_cd = getSecretBytes(_P.cd); tmp_ke = getSecretBytes(_P.ke); s = getSecretBytes(_P.s); ivMac = Mac.getInstance(hmac); ivMac.init(new SecretKeySpec(s, aes)); Mac mac = Mac.getInstance(hmac); PBKDF2 ff = new PBKDF2(mac); byte[] pwkey = ff.generateDerivedParameters(256, pw.getBytes(), s, it); SecretKeySpec seckey = new SecretKeySpec(pwkey, aes); Cipher cipher = Cipher.getInstance(ecb); cipher.init(Cipher.DECRYPT_MODE, seckey); tmp_ke = cipher.doFinal(tmp_ke); seckey = new SecretKeySpec(tmp_ke, aes); cipher.init(Cipher.DECRYPT_MODE, seckey); tmp_ce = cipher.doFinal(tmp_ce); if(Arrays.equals(tmp_cd, tmp_ce)){ KeyGenerator key_gen = KeyGenerator.getInstance(aes); key_gen.init(256); long max = System.currentTimeMillis() % 11; max++; for(int i=0; i < max; i++) key_gen.generateKey(); SecretKey new_key = key_gen.generateKey(); byte[] tmp_k = new_key.getEncoded(); seckey = new SecretKeySpec(tmp_k, aes); cipher.init(Cipher.ENCRYPT_MODE, seckey); tmp_esk = cipher.doFinal(tmp_ke); kcipher = Cipher.getInstance(ecb); kcipher.init(Cipher.DECRYPT_MODE, seckey); return true; } else{ JOptionPane.showOptionDialog(null, "The password is wrong.", Base.appname, JOptionPane.PLAIN_MESSAGE, JOptionPane.WARNING_MESSAGE, null, new Object[]{" OK "}, null); } } catch (Exception e) { e.printStackTrace(); } return false; } //Properties static Properties keyprops = new Properties(); static File secretpropFile; //Properties for secrets static void saveSecret(_P key, String val){ saveSecret(key.name(), val); } static void saveSecret(_P key, byte[] val){ saveSecret(key.name(), Base64.encodeBase64URLSafeString(val)); } static void saveSecret(_P key, int val){ saveSecret(key.name(), val + ""); } static void saveSecret(String key, String val){ try { keyprops.setProperty(key, val); FileOutputStream fos = new FileOutputStream(secretpropFile); keyprops.store(fos, appname); fos.flush(); fos.close(); } catch (Exception e) { e.printStackTrace(); } } static String getSecret(_P key){ return keyprops.getProperty(key.name(), null); } static int getSecretInt(_P key){ try { return Integer.parseInt(keyprops.getProperty(key.name(), null)); } catch (Exception e) { return -1; } } static byte[] getSecretBytes(_P key){ return Base64.decodeBase64(keyprops.getProperty(key.name(), null)); } static void initSecretProps(File path){ secretpropFile = new File(path, file_secret); } private static String mainfolder = null; private static File folderfile = null; static final File getFolderfile() { return folderfile; } static final String getFolder() { return mainfolder; } static final void setFolder(String folder) { if (mainfolder == null) { mainfolder = folder; folderfile = new File(folder); } } static final void setFolder(File folder) { if (mainfolder == null) { mainfolder = folder.getAbsolutePath(); folderfile = folder; } } static final File getNewfile(String filename) { return new File(folderfile, filename); } static final File getArchFolder(String folder){ return new File(folder, appname + "_Export"); } static final File getArchFolder(File folder){ return new File(folder, appname + "_Export"); } static void dialog_createpw(final StringResult srX){ PWTriggerCreate.main(new StringResult() { @Override void receive(String ret) { try { KeyGenerator key_gen = KeyGenerator.getInstance(aes); key_gen.init(256); long max = System.currentTimeMillis() % 11; max++; //Don't know if it is meaningful, but sure it does not hurt! for(int i=0; i < max; i++) key_gen.generateKey(); SecretKey new_key = key_gen.generateKey(); int its = new Random(System.currentTimeMillis()).nextInt(1000) + 6000; byte[] s = new_key.getEncoded(); for(int i=0; i < max; i++) key_gen.generateKey(); new_key = key_gen.generateKey(); byte[] k = new_key.getEncoded(); for(int i=0; i < max; i++) key_gen.generateKey(); new_key = key_gen.generateKey(); byte[] c_dec = new_key.getEncoded(); Mac mac = Mac.getInstance(hmac); PBKDF2 ff = new PBKDF2(mac); byte[] pwkey = ff.generateDerivedParameters(256, ret.getBytes(), s, its); SecretKeySpec seckey = new SecretKeySpec(pwkey, aes); Cipher cipher = Cipher.getInstance(ecb); cipher.init(Cipher.ENCRYPT_MODE, seckey); saveSecret(_P.ke, Base64.encodeBase64URLSafeString(cipher.doFinal(k))); seckey = new SecretKeySpec(k, aes); cipher.init(Cipher.ENCRYPT_MODE, seckey); saveSecret(_P.ce, Base64.encodeBase64URLSafeString(cipher.doFinal(c_dec))); saveSecret(_P.cd, Base64.encodeBase64URLSafeString(c_dec)); saveSecret(_P.s, Base64.encodeBase64URLSafeString(s)); saveSecret(_P.i, its); loadpw(ret); srX.receive(null); } catch (Exception e) { e.printStackTrace(); } } }); } }