0

Since yesterday when I posted the frist time I learned a lot. So what I am trying to do now is to implement user console input instead of the given values, written in bold, encrypt, save them in the file and then keep verifying next user input with the encrypted values saved in the file until correct or up to 10 times.

 String openPwd = "my password is datasecurity";
 String openUser = "a user is ME";

The first question is: can I implement second user input and verification in the same main method of the class?

Moreover I encrypt values with two way encryption AES (Now I know that is not the safest way to encrypt) and one way encryption with hash and salt would be the safest option due to the number of reasons. Also I save password and key in the system file, since setting up database would be too time consuming for the task.

The second question is: can I use PBKDF2 and salt instead of encryption with AES if I do not save password and user name in dbms, but in system file instead? How will verification process in encryption case and PBKDF2 with salt differ?

public class PasswordEncryption {

    public static final String AES = "AES";

    public static String encrypt(String value, File keyFile)
            throws GeneralSecurityException, IOException {
        if (!keyFile.exists()) {
            KeyGenerator keyGen = KeyGenerator
                    .getInstance(PasswordEncryption.AES);

            keyGen.init(128);
            SecretKey sk = keyGen.generateKey();
            FileWriter fw = new FileWriter(keyFile);
            fw.write(byteArrayToHexString(sk.getEncoded()));
            fw.flush();
            fw.close();
        }

        SecretKeySpec sks = getSecretKeySpec(keyFile);
        Cipher cipher = Cipher.getInstance(PasswordEncryption.AES);
        cipher.init(Cipher.ENCRYPT_MODE, sks, cipher.getParameters());
        byte[] encrypted = cipher.doFinal(value.getBytes());
        return byteArrayToHexString(encrypted);
    }

    public static String decrypt(String message, File keyFile)
            throws GeneralSecurityException, IOException {
        SecretKeySpec sks = getSecretKeySpec(keyFile);
        Cipher cipher = Cipher.getInstance(PasswordEncryption.AES);
        cipher.init(Cipher.DECRYPT_MODE, sks);
        byte[] decrypted = cipher.doFinal(hexStringToByteArray(message));
        return new String(decrypted);
    }

    private static SecretKeySpec getSecretKeySpec(File keyFile)
            throws NoSuchAlgorithmException, IOException {
        byte[] key = readKeyFile(keyFile);
        SecretKeySpec sks = new SecretKeySpec(key, PasswordEncryption.AES);
        return sks;
    }

    private static byte[] readKeyFile(File keyFile)
            throws FileNotFoundException {
        @SuppressWarnings("resource")
        Scanner scanner = new Scanner(keyFile).useDelimiter("\\Z");
        String keyValue = scanner.next();
        scanner.close();
        return hexStringToByteArray(keyValue);
    }

    private static String byteArrayToHexString(byte[] b) {
        StringBuffer sb = new StringBuffer(b.length * 2);
        for (int i = 0; i < b.length; i++) {
            int v = b[i] & 0xff;
            if (v < 16) {
                sb.append('0');
            }
            sb.append(Integer.toHexString(v));
        }
        return sb.toString().toUpperCase();
    }

    private static byte[] hexStringToByteArray(String s) {
        byte[] b = new byte[s.length() / 2];
        for (int i = 0; i < b.length; i++) {
            int index = i * 2;
            int v = Integer.parseInt(s.substring(index, index + 2), 16);
            b[i] = (byte) v;
        }
        return b;
    }

    public static void main(String[] args) throws Exception {
        final String KEY_FILE = "/Users/xxx/key";
        final String PASSWORD_FILE = "/Users/xxx/properties";

        String openPwd = "my password is datasecurity";
        String openUser = "a user is ME";

        Properties p1 = new Properties();

        String encryptedPwd = PasswordEncryption.encrypt(openPwd, new File(
                KEY_FILE));
        String encryptedUser = PasswordEncryption.encrypt(openUser, new File(
                KEY_FILE));
        p1.put("password",encryptedPwd);
        p1.put("user",encryptedUser);
        p1.store(new FileWriter(PASSWORD_FILE),"");

        // ==================
        Properties p2 = new Properties();

        p2.load(new FileReader(PASSWORD_FILE));
        encryptedPwd = p2.getProperty("password");
        encryptedUser = p2.getProperty("user");
        System.out.println(encryptedPwd);
        System.out.println(encryptedUser);
        System.out.println(PasswordEncryption.decrypt(encryptedPwd, new File(
                KEY_FILE)));
        System.out.println(PasswordEncryption.decrypt(encryptedUser, new File(
                KEY_FILE)));
    }
}
Clashsoft
  • 11,553
  • 5
  • 40
  • 79
Na Dia
  • 195
  • 1
  • 4
  • 11
  • 1
    If you want values passed from one method to another I suggest you call one method from the other passing the value you want to pass as arguments. – Peter Lawrey Nov 10 '15 at 22:25
  • I would rethink your program's design, particularly the fact that you have two main methods. Think about how you want your classes to interact with each other and make sure they fulfill only their intended purpose. – kmecpp Nov 11 '15 at 03:43

1 Answers1

0

There are two simple ways of doing this. The first would be to create a static class level variable in your first class that contains the value of the encryptedPwd. To make a class level variable you would define it like this:

public class FirstClass {

    public static String encryptedPwd = "";

    public static void main(String[] args){
        ...
        FirstClass.encryptedPwd = encryptedPwd; //Set the class level variable equal to the encrypted password
        ...
    }

}

Then you could access it from your Authenticate class using:

if (FirstClass.encryptedPwd.equals(inputHash)) //Getting the password variable in Authenticate class

or you could create a static method to access it as well which would allow you to keep the variable private.

public static String getPassword(){ //Static Method inside your first class that returns the encrypted password
    return encryptedPwd;
}

if(FirstClass.getPassword().equals(inputHash)) //Method call in Authenticate class

There are other options too, but it depends on what your doing and the design you want for your project

kmecpp
  • 2,371
  • 1
  • 23
  • 38
  • I receive an error when try to implement static method to access variable that says: cannot resolve *encryptedPwd* to variable and gives suggestion below: public static String getPassword(){ return encrypt(null, null); } – Na Dia Nov 11 '15 at 01:28
  • The first advice on implementing a static class level variable in my *first class* that contains the value of the encryptedPwd and access it from your Authenticate class using hmm.. is difficult. How can it be static if it is calculated hash value from *openPwd*? – Na Dia Nov 11 '15 at 01:33
  • @NaDia I updated the post to hopefully clarify how to create and use the variable, you would set the value of the static variable equal to the calculated hash value. It doesn't need to be static if you have an instance of your first class but its hard to tell what your doing. Particularly because you have two main methods and no class definition for the first one. – kmecpp Nov 11 '15 at 01:40
  • imho I don't think putting such kind of data as static variable is a wise choice – Adrian Shum Nov 11 '15 at 02:01
  • @AdrianShum neither do I, but do you have a better suggestion that doesn't involve rewriting all of the OP's code? – kmecpp Nov 11 '15 at 03:10
  • Actually I don't know how your code works without big change in OP's code either :P He has 2 classes, each with its own main method. Which implies that he is going to run main method one-by-one. Even you put the `encryptedPassword` as static var, it won't persist when OP run the 2nd class' main method – Adrian Shum Nov 11 '15 at 03:15
  • @AdrianShum I'm pretty sure the duplicate main method was unintentional. I assumed he was running the main method from what he called the 'First' class – kmecpp Nov 11 '15 at 03:31
  • @kmecpp at least I cannot see his intention. Neither of the main methods is trying to use the other class. I should say his design is really poorly done that no one can get a sane interpretation on what he is trying to do :P – Adrian Shum Nov 11 '15 at 03:35
  • @AdrianShum I agree completely – kmecpp Nov 11 '15 at 03:40
  • Hey Guys! thanks for the comments and brainstorming here. – Na Dia Nov 11 '15 at 19:40
  • Yes my design is far from being perfect and I think I can remove Authenticate class, as the intention with my code is to: 1) **encrypt password**, 2) **save it in the file**, 3) which I hoped will be accomplished with Authenticate class: **hash user log in credentials entered from the console**, **verify user log in credentials with the hash value in the file**. I think I can implement 3) in the First class and remove Authenticate class completely. If you have good suggestions on how to implement **user input** and **verification** in the Fist class, I would be grateful to learn. – Na Dia Nov 11 '15 at 19:47
  • Thank you @kmecpp for the comments and help! – Na Dia Nov 11 '15 at 19:52
  • @NaDia If you explain what exactly your ultimately trying to accomplish and what you want your final program to do, I'd be able to point you in the right direction. – kmecpp Nov 11 '15 at 19:56
  • Thank you @PeterLawrey! calling from one method to another by passing values as arguments might work I suppose. Can I implement: **1) encrypt password encryption, 2) file save, 3) hash user log in credentials entered from the console, verify user log in credentials with the hash value in the file** in one method of the first class? Would it be correct OOP code design? – Na Dia Nov 11 '15 at 19:58
  • @kmecpp I have posted detailed program goal 10 min ago. Can you see my comment? Sorry if my explanation was really bad: **1) encrypt password with the hash of the key value (Accomplished in First Class), 2) save it in the file (Accomplished in First Class), 3) encrypt user log in credentials (entered from the console) with the same hash key, 4) verify user log in credentials by comparing it to the hash value of the password saved in the file. - Last two points yet to be accomplished/implemented**. **Goal: is to implement safe storage and password verification** – Na Dia Nov 11 '15 at 20:05
  • So all your really trying to do is read the hashed password from the file and compare THAT with the hashed value, imputed from the console? – kmecpp Nov 11 '15 at 20:07
  • @kmecpp **+ encrypting password and username**. Yes:) So: enter user name and password from the console -> encrypt -> compare hash values with the hash values in the file -> keep on entering password up to 10 times or until matches the hash value of password in the file:) – Na Dia Nov 11 '15 at 20:10
  • In that case your question really just becomes: how to read data from a file in Java which there are already plenty of answers to See: http://stackoverflow.com/a/2864148/3476226 for an example. And on a side note, hashing is different from encryption. Hashing doesn't have a 'key', you can read up on the difference here: http://stackoverflow.com/a/326706/3476226 – kmecpp Nov 11 '15 at 20:15
  • Thank you for the links on hashing and encryption @kmecpp! But can I implement last two points in the main method of the First Class ?: **3) encrypt user log in credentials (entered from the console) with the same hash key, 4) verify user log in credentials by comparing it to the hash value of the password saved in the file** – Na Dia Nov 11 '15 at 20:18
  • Is the password your checking the input against "my password is datasecurity" or does the user input a password at some point? – kmecpp Nov 11 '15 at 20:22
  • @kmecpp i will check against user input password. So instead of "my password is datasecurity" I will have scanner in... : **user input** – Na Dia Nov 11 '15 at 20:38
  • Can you update the code in your post with what you have currently – kmecpp Nov 11 '15 at 20:43