Erinevus lehekülje "ITI0011:harjutus 16" redaktsioonide vahel

Allikas: Kursused
Mine navigeerimisribale Mine otsikasti
26. rida: 26. rida:
  
 
<source lang="java">
 
<source lang="java">
 +
 
/**
 
/**
 
  * Created by odin on 20.04.15.
 
  * Created by odin on 20.04.15.
 
  */
 
  */
 
+
 
import java.io.*;
 
import java.io.*;
 
import java.security.MessageDigest;
 
import java.security.MessageDigest;
35. rida: 36. rida:
 
import java.util.Properties;
 
import java.util.Properties;
 
import java.util.Scanner;
 
import java.util.Scanner;
 
+
public class Main {
+
public class FromTemplate {
 
+
 
     public static final String INPUT_FILE  = "user.properties";
 
     public static final String INPUT_FILE  = "user.properties";
 
     public  static final String OUTPUT_FILE  = "newUser.properties";
 
     public  static final String OUTPUT_FILE  = "newUser.properties";
 
     public static final int LENGTH_OF_SALT  = 10;
 
     public static final int LENGTH_OF_SALT  = 10;
 
     public static final int MAX_CHANCES_COUNT = 3;
 
     public static final int MAX_CHANCES_COUNT = 3;
 
+
 
     public static void main(String[] args) {
 
     public static void main(String[] args) {
 
         try {
 
         try {
 
             // check whether a user with a hashed password already exists
 
             // check whether a user with a hashed password already exists
 
             if(new File(OUTPUT_FILE).isFile()) {
 
             if(new File(OUTPUT_FILE).isFile()) {
                 HashMap<String, String> data = readUserDataFromFile(OUTPUT_FILE);
+
                 HashMap<String, String> data = readDataFromFile(OUTPUT_FILE);
 
                 if (data == null) {
 
                 if (data == null) {
 
                 System.out.println("Data from " + OUTPUT_FILE + " cannot be read");
 
                 System.out.println("Data from " + OUTPUT_FILE + " cannot be read");
58. rida: 59. rida:
 
             } else {
 
             } else {
 
                 // "register" new user with salted hash
 
                 // "register" new user with salted hash
                 HashMap<String, String> data = readUserDataFromFile(INPUT_FILE);
+
                 HashMap<String, String> data = readDataFromFile(INPUT_FILE);
 
                 if (data == null) {
 
                 if (data == null) {
 
                 System.out.println("data cannot be read");
 
                 System.out.println("data cannot be read");
70. rida: 71. rida:
 
                 String salt    = md5MyString("saltyRandomString").substring(0, LENGTH_OF_SALT);
 
                 String salt    = md5MyString("saltyRandomString").substring(0, LENGTH_OF_SALT);
 
                 password        = md5MyString(password + salt);
 
                 password        = md5MyString(password + salt);
                 saveNewUserData(username, password, salt);
+
                 boolean result = saveNewUserData(username, password, salt);
 +
                if (!result) {
 +
                System.out.println("Storing hashed data did not work properly.");
 +
                System.exit(3);
 +
                }
 
             }
 
             }
 
         } catch (Exception e) {
 
         } catch (Exception e) {
76. rida: 81. rida:
 
         }
 
         }
 
     }
 
     }
 
+
 
     public static void authenticate(String username, String password, String salt) throws Exception {
 
     public static void authenticate(String username, String password, String salt) throws Exception {
 
         Scanner userInput = new Scanner(System.in);
 
         Scanner userInput = new Scanner(System.in);
94. rida: 99. rida:
 
             System.out.println("Sorry, You didn't guess " + username + "'s password");
 
             System.out.println("Sorry, You didn't guess " + username + "'s password");
 
     }
 
     }
 
+
     public static HashMap<String, String> readUserDataFromFile(String filename) throws IOException {
+
    /**
 +
    * Reads all the properties from the given input file and returns
 +
    * a key-value mapping of the contents in the file.
 +
    * In case the file is corrupted or something goes wrong, returns null.
 +
    * @param filename File to be read.
 +
    * @return Hash map of settings in the file, NULL if something goes wrong.
 +
    */
 +
     public static HashMap<String, String> readDataFromFile(String filename) {
 
         return null;
 
         return null;
 
     }
 
     }
 
+
     public static void saveNewUserData(String username, String password, String salt) throws IOException {
+
    /**
 +
    * Writes username, password and salt values to
 +
    * the corresponding keys (username, password, salt).
 +
    * in the file OUTPUT_FILE.
 +
    * In case the data is successfully stored, returns true.
 +
    * If something goes wrong, returns false.
 +
    * You have to use saveData method inside this method.
 +
    * You have to modify the call to saveData in order to
 +
    * pass the correct key-value map. The actual writing
 +
    * will be done in saveData method.
 +
    * @param username The value of username.
 +
    * @param password The value of hashed password.
 +
    * @param salt The value of salt.
 +
    * @return true if data is stored, false otherwise.
 +
    */
 +
     public static boolean saveNewUserData(String username, String password, String salt) {
 +
    // TODO: data to be saved
 +
    return saveData(OUTPUT_FILE, null);
 +
    }
 +
   
 +
    /**
 +
    * Writes key-values from data into properties file which is given
 +
    * by filename. If the file does not exist, the file is created.
 +
    * @param filename The file name to be saved.
 +
    * @param data The data to be stored in the file.
 +
    * @return true, if the file is successfully stored, false otherwise.
 +
    */
 +
    public static boolean saveData(String filename, HashMap<String, String> data) {
 +
    return false;
 
     }
 
     }
 
 
     /*
 
     /*
 
     * Maagia, sellest ei pea aru saama.
 
     * Maagia, sellest ei pea aru saama.
118. rida: 157. rida:
 
         return result;
 
         return result;
 
     }
 
     }
 
+
 
}
 
}
 
</source>
 
</source>

Redaktsioon: 21. aprill 2015, kell 23:54

Kirjeldus

Kirjutada programm, mis loeb etteantud properties-failist kasutajanime ja parooli ning salvestab turvalisema variandi teise faili. Teise faili salvestatakse sama kasutaja andmed, aga parool on soolatud räsina (salted hash). Mõlemad failid on properties-tüüpi failid (vt viiteid allpool).

Algne fail (user.properties):

username=Juku
password=raskeparool123

Teie peate implementeerima failist lugemise ja kirjutamise meetodid - vastavalt readUserDataFromFile ja saveNewUserDataToFile.

Programm kontrollib, kas on olemas räsitud parooliga fail "newUser.properties". Kui see puudub, siis tehakse see fail SaveNewUserDataToFile meetodiga. Uues failis peavad olema võtmesõnad: "username", "password" ja "salt". Kui aga käivitamisel eksisteerib "newUser.properties" mõnest eelnevast käitamisest, siis programm kutsub esile authenticate meetodi, mis laseb kasutajal parooli pakkuda.

Esmalt oleks mõistlik realiseerida readUserDataFromFile meetod, kuna uue faili andmed on otseses sõltuvuses meie antud faili sisust - mida võib vabalt muuta, aga kindlasti peavad olema võtmesõnad "username" ja "password". Meetod readUserDataFromFile peab tagastama HashMap tüüpi objekti, mille võtmed ja väärtused on täpselt need, mis user.properties failis.

Lugemine soolatud räsimise kohta: https://crackstation.net/hashing-security.htm

Kui pikad tekstid pole päris Teie rada, siis järgmine link on ka piisav lugemine: http://security.stackexchange.com/questions/51959/why-are-salted-hashes-more-secure

Kiire ülevaade Java Propertiesist: http://www.mkyong.com/java/java-properties-file-examples/


Mall

<source lang="java">

/**

* Created by odin on 20.04.15.
*/

import java.io.*; import java.security.MessageDigest; import java.util.HashMap; import java.util.Properties; import java.util.Scanner;

public class FromTemplate {

   public static final String INPUT_FILE   = "user.properties";
   public  static final String OUTPUT_FILE  = "newUser.properties";
   public static final int LENGTH_OF_SALT  = 10;
   public static final int MAX_CHANCES_COUNT = 3;

   public static void main(String[] args) {
       try {
           // check whether a user with a hashed password already exists
           if(new File(OUTPUT_FILE).isFile()) {
               HashMap<String, String> data = readDataFromFile(OUTPUT_FILE);
               if (data == null) {
               	System.out.println("Data from " + OUTPUT_FILE + " cannot be read");
               	System.exit(2);
               }
               String username = data.get("username");
               String password = data.get("password");
               String salt     = data.get("salt");
               authenticate(username, password, salt);
           } else {
               // "register" new user with salted hash
               HashMap<String, String> data = readDataFromFile(INPUT_FILE);
               if (data == null) {
               	System.out.println("data cannot be read");
               	System.out.println("(file does not exist, is corrupted, "
               			+ "or readUserDataFromFile not implemented).");
               	System.out.println("Exiting.");
               	System.exit(1);
               }
               String username = data.get("username");
               String password = data.get("password");
               String salt     = md5MyString("saltyRandomString").substring(0, LENGTH_OF_SALT);
               password        = md5MyString(password + salt);
               boolean result = saveNewUserData(username, password, salt);
               if (!result) {
               	System.out.println("Storing hashed data did not work properly.");
               	System.exit(3);
               }
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

   public static void authenticate(String username, String password, String salt) throws Exception {
       Scanner userInput = new Scanner(System.in);
       String guess;
       System.out.println("Hello, You now have " + MAX_CHANCES_COUNT + " chances to guess " + username + "'s password.");
       int chances;
       for (chances = MAX_CHANCES_COUNT - 1; chances >= 0; chances--) {
           guess = userInput.next();
           if (md5MyString(guess + salt).equals(password)) {
               System.out.println("That's correct!");
               break;
           } else if (chances > 0) {
               System.out.println("That's invalid! " + chances + " guess" + (chances > 1 ? "es" : "") + " left.");
           }
       }
       if (chances < 0)
           System.out.println("Sorry, You didn't guess " + username + "'s password");
   }

   /**
    * Reads all the properties from the given input file and returns 
    * a key-value mapping of the contents in the file.
    * In case the file is corrupted or something goes wrong, returns null.
    * @param filename File to be read.
    * @return Hash map of settings in the file, NULL if something goes wrong.
    */
   public static HashMap<String, String> readDataFromFile(String filename) {
       return null;
   }

   /**
    * Writes username, password and salt values to 
    * the corresponding keys (username, password, salt).
    * in the file OUTPUT_FILE.
    * In case the data is successfully stored, returns true.
    * If something goes wrong, returns false.
    * You have to use saveData method inside this method.
    * You have to modify the call to saveData in order to
    * pass the correct key-value map. The actual writing
    * will be done in saveData method.
    * @param username The value of username.
    * @param password The value of hashed password.
    * @param salt The value of salt.
    * @return true if data is stored, false otherwise.
    */
   public static boolean saveNewUserData(String username, String password, String salt) {
   	// TODO: data to be saved
   	return saveData(OUTPUT_FILE, null);
   }
   
   /**
    * Writes key-values from data into properties file which is given
    * by filename. If the file does not exist, the file is created.
    * @param filename The file name to be saved.
    * @param data The data to be stored in the file.
    * @return true, if the file is successfully stored, false otherwise.
    */
   public static boolean saveData(String filename, HashMap<String, String> data) {
   	return false;
   }
   /*
   * Maagia, sellest ei pea aru saama.
   * tl;dr:
   * Hashimist on vaja, et andmete hoiustamisel poleks
   * privaatsed andmed (loe: paroolid) lihtsasti loetavad
   * */
   public static String md5MyString(String str) throws Exception {
       MessageDigest m = MessageDigest.getInstance("MD5");
       m.update(str.getBytes("UTF8"));
       byte s[] = m.digest();
       String result = "";
       for (int i = 0; i < s.length; i++) {
           result += Integer.toHexString((0x000000ff & s[i]) | 0xffffff00).substring(6);
       }
       return result;
   }

} </source>