Password Manager
- Zhiming SU
- Mar 6, 2018
- 13 min read
Description:
This project is one of my best project, which is over thousands of lines of code about to save and secure user's information. This project covered some basic knowledge of Encryptions by using "SHA-512" with IV, also using merkle_tree_hashing for check_integraty to see if any information been modified without user's confirmation.
This program will output 2 text file named master_passwd.txt and passwd_file.txt, and all information will be stored into byte array into these 2 files.
master_passwd.txt will store IV and the password for the program itself. And the passwd_file.txt will store the [hash_code]+[IV]+[Users' information]. and [Users' information] will be like [length of the 1st username]+[1st username]+[length of the 1st user's password]+[1st user's password]+[length of the 1st user's domain_name]+[1st user's domain_name]+[2nd user.....
This program contain 5 functions, including register_accountenter, check_integraty, delete_account, change_account, and get_passward.
The code:
package passwordmanager;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
*
* @author zhiming
*/
class Encryption{
// get a ramdom byte[] of 256-bitlong
static byte[] get_IV(int size){
SecureRandom random = new SecureRandom();
byte[] keyBytes = new byte[size]; //size = 32 for set_master to hash master_password, size = 16 for passwd_file encryption
random.nextBytes(keyBytes);
return keyBytes;
}
static int ranIntGen(){
Random r = new Random();
int put = r.nextInt(9);
return put;
}
static char ranCharGen(){
int rnd = (int) (Math.random() * 52); // or use Random or whatever
char base = (rnd < 26) ? 'A' : 'a';
return (char) (base + rnd % 26);
}
static String ranPassGen(int Len){
String result = "";
for(int i = 0 ; i < Len; i++){
Random r = new Random();
int switchX = r.nextInt(2);
if(switchX == 0){
result = result + ranIntGen();
}
else{
result = result + ranCharGen();
}
}
return result;
}
// take a string of master_passwd and byte[] IV, return a hashed byte[] of master_passwd by using byte[] IV
static byte[] set_master_passwd(String input,byte[] IV) throws NoSuchAlgorithmException, NoSuchProviderException{
byte[] maps = input.getBytes();
byte[] result = new byte[IV.length+maps.length];
for(int i =0;i<result.length;i++){
if( i < IV.length){
result[i] = IV[i];
}
else{
result[i] = maps[i-IV.length];
}
}
MessageDigest mda = MessageDigest.getInstance("SHA-512");
byte [] hashed = mda.digest(result);
return hashed; // it is 64 byte long
}
static byte[] KeyGen() throws Exception{
byte result[] = new byte[16];
result = passwordmanager.TheMas.getBytes();
MessageDigest mda = MessageDigest.getInstance("SHA-512");
byte hashed[] = new byte[16];
hashed = mda.digest(result);
byte hashed1[] = new byte[16];
System.arraycopy(hashed, 0, hashed1, 0, 16);
return hashed1; // it is 16 byte long
}
static byte[] enc(String s, byte IV[] ,byte key[]) throws Exception{
byte data[] = s.getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
// Instantiate the cipher
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(IV));
return cipher.doFinal(data);
}
public static byte[] dec(byte msg[],byte IV[],byte key[]) throws Exception{
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
// Instantiate the cipher
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(IV));
return cipher.doFinal(msg);
}
//given 2 byte[] using SHA512 to hash them toghther
//return a 64byte hashed byte[]
static byte[] myhashing(byte[] a, byte[] b) throws NoSuchAlgorithmException{
byte[] result = new byte[a.length+b.length];
System.arraycopy(a, 0, result, 0, a.length);
System.arraycopy(b, 0, result, 0, b.length);
MessageDigest mda = MessageDigest.getInstance("SHA-512");
byte [] hashed = mda.digest(result);
return hashed; // it is 64 byte long
}
//devide a byte[] in to 4 parts with similar length and then perform merkle_tree_hashing
// finally return the root
static byte[] merkle_tree_hashing(byte[] all) throws NoSuchAlgorithmException{
byte[] node12 = new byte[all.length/2];
byte[] node34 = new byte[all.length-node12.length];
System.arraycopy(all, 0, node12, 0, node12.length);
System.arraycopy(all, node12.length, node34, 0, node34.length);
byte[] node1 = new byte[node12.length/2];
byte[] node2 = new byte[node12.length-node1.length];
byte[] node3 = new byte[node34.length/2];
byte[] node4 = new byte[node34.length-node3.length];
System.arraycopy(node12, 0, node1, 0, node1.length);
System.arraycopy(node12, node1.length, node2, 0, node2.length);
System.arraycopy(node34, 0, node3, 0, node3.length);
System.arraycopy(node34, node3.length, node4 , 0, node4.length);
byte[] node12h = myhashing(node1,node2);
byte[] node34h = myhashing(node3,node4);
byte[] result = myhashing(node12h,node34h);
return result;// 64byte long
}
/* This method will take byte[] the_rest_users and the IV and the key and decrypt the 1st user
return an Object[] with length of 4, which is [e0,e1,e2,e3]
where e0 is first user's username, e1 is the first user's password, e2 first user's domainname
e3 is the rest users byte[](not decrypt yet) and with the 1st user's information removed
*/
static Object[] dec_userifor(byte The_rest[], byte oldIV[], byte key[])throws Exception{
if(The_rest == null){
return null;
}
else{
// this is the result, [e1,e2,e3,e4] where e0 is first user's username, e1 is password, e2 is domain name e3 is
// the rest of the users' information byte array(without decrypted yet), with the fitst user removed
Object[] result = new Object[4];
byte[] Ulen = new byte[4];byte[] Plen = new byte[4]; byte[] Dlen = new byte[4];
System.arraycopy(The_rest, 0, Ulen, 0, Ulen.length);
byte[] UnameE = new byte[ArrayMaster.Convert_4_byte_byteArray_toInt(Ulen)];
System.arraycopy(The_rest, 4, UnameE, 0, UnameE.length);
byte[] UnameD = dec(UnameE,oldIV,key); //Now we have our user name
String U = ArrayMaster.convert_byteArray_to_String(UnameD);
result[0] = U; //collect the username
System.arraycopy(The_rest, 4+UnameE.length, Plen, 0, Plen.length);
byte[] PsswdE = new byte[ArrayMaster.Convert_4_byte_byteArray_toInt(Plen)];
System.arraycopy(The_rest, 4+UnameE.length+4, PsswdE, 0, PsswdE.length);
byte[] PsswdD = dec(PsswdE,oldIV,key);
String P = ArrayMaster.convert_byteArray_to_String(PsswdD);
result[1] = P; //collect the password
System.arraycopy(The_rest, 4+UnameE.length+4+PsswdE.length, Dlen, 0, Dlen.length);
byte[] DominE = new byte[ArrayMaster.Convert_4_byte_byteArray_toInt(Dlen)];
System.arraycopy(The_rest, 4+UnameE.length+4+PsswdE.length + 4, DominE, 0, DominE.length);
byte[] DominD = dec(DominE,oldIV,key);
String D = ArrayMaster.convert_byteArray_to_String(DominD);
result[2] = D; // collect the domainName
byte[] TheNewRest = new byte[The_rest.length - (4+UnameE.length+4+PsswdE.length + 4 + DominE.length)];
System.arraycopy(The_rest, 4+UnameE.length+4+PsswdE.length + 4 + DominE.length, TheNewRest, 0, TheNewRest.length);
result[3] = TheNewRest; //collect the new rest//
return result;
}
}
/* implement the dec_userifor and return a String[] in this form:
[1st username,1st password,1st domainname,2nd username,2nd password,2nd domainname,......,nth username,nth password,nth domainname]
*/
static String[] collection(int length ,byte The_rest[], byte oldIV[], byte key[]) throws Exception{
String[] result = new String[length*3];
for (int i =0; i<result.length ;i +=3){
Object[] cool = dec_userifor(The_rest,oldIV,key);
result[i] = (String) cool[0];
result[i+1] = (String) cool[1];
result[i+2] = (String) cool[2];
The_rest = (byte[]) cool[3];
}
return result;
}
// the Object array is in this form : [1st username,1st password,1st domainname,2nd username,2nd password,3nd domainname,......]
static byte[] enc_alluser(String[] all, byte newIV[], byte key[]) throws Exception{
byte[] result = null;
for (int i = 0; i < (all.length); i+=3) {
byte[] ulen = ArrayMaster.intToBytes(all[i].length());
byte[] UE = enc(all[i],newIV,key);
byte[] Uall = ArrayMaster.combine2array(ulen,UE);
byte[] plen = ArrayMaster.intToBytes(all[i+1].length());
byte[] PE = enc(all[i+1],newIV,key);
byte[] Pall = ArrayMaster.combine2array(plen,PE);
byte[] UandP = ArrayMaster.combine2array(Uall,Pall);
byte[] dlen = ArrayMaster.intToBytes(all[i+2].length());
byte[] DE = enc(all[i+2],newIV,key);
byte[] Dall = ArrayMaster.combine2array(dlen,DE);
byte[] allT = ArrayMaster.combine2array(UandP,Dall);
result = ArrayMaster.combine2array(result,allT);
}
return result;
}
}
class fileMaster{
public static String folderpath;
static void rm_content_fm_passfile() throws FileNotFoundException{
String path = folderpath + "passwd_file.txt";
File file = new File(path);
PrintWriter writer = new PrintWriter(file);
writer.print("");
writer.close();
}
public static String AutofileSearching(){
Scanner input = new Scanner(System.in);
System.out.println("Please enter the path of the folder (include '/' at the end of the path string): ");
String fPath = input.nextLine();
folderpath = fPath;
String s1 = "passwd_file.txt";
String s2 = "master_passwd.txt";
File f1 = new File(folderpath+s1);
File f2 = new File(folderpath+s2);
String result1;
String result2;
if(f1.exists() && !f1.isDirectory()) {
result1 = "founded";
}else{
result1 = "missing";
}
if(f2.exists() && !f2.isDirectory()) {
result2 = "founded";
}else{
result2 = "missing";
}
if("founded".equals(result1) && "founded".equals(result2) ){
System.out.println("file " + s1 + " and " + s2 +" are founded");
return "all founded";
}
else if("missing".equals(result1) && "missing".equals(result2)){
System.out.println("file " + s1 + " and " + s2 +" are missing");
return "all missing";
}
else if(!"missing".equals(result1) && "missing".equals(result2)){
System.out.println("Error, file " + s2 + " is missing");
System.exit(0);
}
else if("missing".equals(result1) && !"missing".equals(result2)){
System.out.println("Error, file " + s1 + " is missing");
System.exit(0);
}
return null; // this line is not supposed to be reached.
}
static byte[] read_all_fm_passfile() throws IOException{
String wholePath = folderpath + "passwd_file.txt";
Path path = Paths.get(wholePath);
byte[] data = Files.readAllBytes(path);
return data;
}
public static byte[] read_IV_fm_passfile() throws IOException{
byte[] data = read_all_fm_passfile();
byte[] IV = new byte[16];
// IV is 16 byte long
System.arraycopy(data, 64, IV, 0, IV.length);
return IV;
}
static byte[] read_Root_fm_passfile() throws IOException{
byte[] data = read_all_fm_passfile();
byte[] Root = new byte[64];
System.arraycopy(data, 0, Root, 0, 64);
return Root;
}
static byte[] read_Num_of_user_fm_passfile() throws IOException{
byte[] data = read_all_fm_passfile();
byte[] Num_of_user = new byte[4]; // the number is an integer, so it should be 4 byte long
// Num_of_user is after root and IV, where root is 64-byte, and IV is 16-byte
System.arraycopy(data, 80, Num_of_user, 0, Num_of_user.length);
return Num_of_user;
}
static byte[] read_all_users_infor_fm_passfile() throws IOException{
byte[] data = read_all_fm_passfile();
//64 is the root length, 16 is IV length, 4 is the number of user length
byte[] all_users_infor = new byte[data.length - (64 + 16 + 4)];
System.arraycopy(data, 64 + 16 + 4, all_users_infor, 0, all_users_infor.length);
return all_users_infor;
}
public static boolean chick_if_passwd_file_empty() throws IOException{
String wholePath = folderpath + "passwd_file.txt";
Path path = Paths.get(wholePath);
byte[] data = Files.readAllBytes(path);
String datas = "";
for(int i = 0; i < data.length;i++){
datas = datas+data[i];
}
if(datas == ""){
return true;
}else{
return false;
}
}
static void write_everything_into_master_file(byte[] IV, byte[] hashed_master) throws FileNotFoundException, IOException{
FileOutputStream fos = new FileOutputStream(fileMaster.folderpath+"master_passwd.txt");
fos.write(IV);
fos.write(hashed_master);
fos.close();
}
static void write_everything_into_password_file(byte[] root, byte[] IV, byte[] The_rest ) throws FileNotFoundException, IOException{
FileOutputStream fos = new FileOutputStream(fileMaster.folderpath+"passwd_file.txt");
fos.write(root);
fos.write(IV);
fos.write(The_rest);
fos.close();
}
public static byte[] fileReader(String p){
String wholePath = p;
try{
//read test file content into string
Path path = Paths.get(wholePath);
byte[] data = Files.readAllBytes(path);
return data;
}
catch(Exception e){
byte[] m = new byte[64];
return (m); // if there is no such a file then return null for the file content
}
}
}
class ArrayMaster{
static byte[] intToBytes( int i ) {
ByteBuffer bb = ByteBuffer.allocate(4);
bb.putInt(i);
return bb.array();
}
static String[] combine2StingArray(String[] a, String[] b){
if(a == null){
return b;
}
else if(b == null){
return a;
}
if(a==null && b == null){
return null;
}
String[] all = new String[a.length+b.length];
System.arraycopy(a ,0 ,all ,0 ,a.length);
System.arraycopy(b, 0, all, a.length, b.length);
return all;
}
static byte[] combine2array(byte[] a, byte[] b){
if(a == null){
return b;
}
else if(b == null){
return a;
}
if(a==null && b == null){
return null;
}
byte[] all = new byte[a.length+b.length];
System.arraycopy(a ,0 ,all ,0 ,a.length);
System.arraycopy(b, 0, all, a.length, b.length);
return all;
}
static byte[] combine6array(byte[] a,byte[] b,byte[] c,byte[] d,byte[] e,byte[] f){
byte[] ab = combine2array(a,b);
byte[] cd = combine2array(c,d);
byte[] ef = combine2array(e,f);
byte[] abcd = combine2array(ab,cd);
byte[] abcdef = combine2array(abcd,ef);
return abcdef;
}
static int Convert_4_byte_byteArray_toInt(byte[] bytes) {
int value = 0;
for (int i = 0; i < 4; i++) {
int shift = (4 - 1 - i) * 8;
value += (bytes[i] & 0x000000FF) << shift;
}
return value;
}
static String convert_byteArray_to_String(byte[] bytes){
return new String(bytes);
}
}
public class passwordmanager{
static String TheMas;
private static void register_account() throws NoSuchAlgorithmException, IOException, Exception{
// Start to input username, password, and domain name
System.out.println("Please enter the username, and make sure it's no longer than 80 characters");
Scanner input1 = new Scanner(System.in);
String username = input1.nextLine();
System.out.println("Please enter the password, and make sure it's no longer than 80 characters");
Scanner input2 = new Scanner(System.in);
String password = input2.nextLine();
System.out.println("Please enter the domain name, and make sure it's no longer than 80 characters");
Scanner input3 = new Scanner(System.in);
String domainname = input3.nextLine();
// Start to encrypt
//which means the passwd.file is empty, you have't register anything
if(fileMaster.chick_if_passwd_file_empty() == true){
byte[] IV = Encryption.get_IV(16); //128-bit long
byte[] key = Encryption.KeyGen();
byte[] my_username = Encryption.enc(username, IV, key);
byte[] my_password = Encryption.enc(password, IV, key) ;
byte[] my_domainname = Encryption.enc(domainname, IV, key) ;
byte[] length_of_username = ArrayMaster.intToBytes(my_username.length);
byte[] length_of_password = ArrayMaster.intToBytes(my_password.length);
byte[] length_of_domainame = ArrayMaster.intToBytes(my_domainname.length);
byte[] Number_of_the_user = ArrayMaster.intToBytes(1); // cuz this is the 1st time to register only one user we have now
//now perform merkle_tree_hashing
byte[] registerInfor = ArrayMaster.combine6array(length_of_username,my_username,
length_of_password,my_password,
length_of_domainame,my_domainname);
byte[] all = ArrayMaster.combine2array(Number_of_the_user, registerInfor);
byte[] root = Encryption.merkle_tree_hashing(registerInfor);
//now write everything into password_file.txt
fileMaster.write_everything_into_password_file(root, IV, all);
continues();
}
//However, if it is not the first time, then we need to read some data from the orginary password_file.txt and edit them
// we need the new root, cuz we add one more user now
// we need a new IV, we also need to read the ogginary IV from the file, then use it to decrypt the users' information
// we need to read how many users we have and incrment the Number of the users by 1
else{
//get the Num of the User first
byte [] num_of_user = fileMaster.read_Num_of_user_fm_passfile();
int num_of_users = ArrayMaster.Convert_4_byte_byteArray_toInt(num_of_user);
byte[] old_IV = fileMaster.read_IV_fm_passfile();
byte[] all_users_infor = fileMaster.read_all_users_infor_fm_passfile();
byte[] key = Encryption.KeyGen();
// now we 1st decrypt all the users and put into a String[] in this form
//[1st username,1st password,1st domainname,2nd username,2nd password,2nd domainname,......,nth username,nth password,nth domainname]
String[] allInfor = Encryption.collection(num_of_users,all_users_infor,old_IV,key);
// now we need to check if the (username,domainname) all mathche what have already input the allInfor
for(int i = 0; i < allInfor.length; i+=3){
if(allInfor[i] == username && allInfor[i+2] == domainname){
System.out.println("You have already register this account");
System.exit(0);
}
}
// When we passed the check we can now put our new accunt by the end of the array
String[] newAllInfor = new String[allInfor.length+3];
System.arraycopy(allInfor, 0, newAllInfor, 0, allInfor.length);
newAllInfor[allInfor.length] = username;
newAllInfor[allInfor.length+1] = password;
newAllInfor[allInfor.length+2] = domainname;
// Now we use new IV to encrypt this String[] into byte[]
num_of_users++;
byte[] new_num_of_user = ArrayMaster.intToBytes(num_of_users); // this is our new byte array of the int
byte[] new_IV = Encryption.get_IV(16);
byte[] newUsers = Encryption.enc_alluser(newAllInfor,new_IV,key);
// Then do the merkle_tree_hashing to get the new root
byte[] new_root = Encryption.merkle_tree_hashing(newUsers);
byte[] new_all = ArrayMaster.combine2array(new_num_of_user, newUsers);
// Now replace all the [old root,old IV, old number_of_user, old userinfor]
// with [new root, new IV, new number_of_user, new userinfor]
fileMaster.rm_content_fm_passfile();
fileMaster.write_everything_into_password_file(new_root,new_IV,new_all);
continues();
}
}
private static String check_integraty() throws IOException, NoSuchAlgorithmException {
//we need to check first, if you haven't register any account yet, and you only created those 2 files
// you don't need to check_integraty, because there is nothing in the pass_file
if(fileMaster.chick_if_passwd_file_empty()==true){
System.out.println("you haven't register any account yet, there is no need to check_integraty.");
return "success";
}
// first we need to read all user infor from password_file
byte allUser[] = fileMaster.read_all_users_infor_fm_passfile();
// Then we read the root fm the file
byte root[] = fileMaster.read_Root_fm_passfile();
// then we perform Encryption.merkle_tree_hashing
byte root1[] = Encryption.merkle_tree_hashing(allUser);
// then we check if the are same
for(int i = 0; i<64;i++){
if(root[i] != root1[i]){
System.out.println("the check_integraty is filed, your infor been changed by the unknown adversaries");
return "fail";
}
}
System.out.println("The check_integraty is success");
return "success";
}
private static void delete_account() throws NoSuchAlgorithmException, IOException, Exception {
System.out.println("Please enter the username, that you wanna delate");
Scanner input1 = new Scanner(System.in);
String username = input1.nextLine();
System.out.println("Please enter the password, that you wanna delate");
Scanner input2 = new Scanner(System.in);
String password = input2.nextLine();
System.out.println("Please enter the domain name, that you wanna delate");
Scanner input3 = new Scanner(System.in);
String domainname = input3.nextLine();
byte oldIV[] = fileMaster.read_IV_fm_passfile();
byte key[] = Encryption.KeyGen();
byte oldNum[] = fileMaster.read_Num_of_user_fm_passfile();
int oldNUM = ArrayMaster.Convert_4_byte_byteArray_toInt(oldNum);
byte oldUser[] = fileMaster.read_all_users_infor_fm_passfile();
String oldUserInfor[] = Encryption.collection(oldNUM, oldUser, oldIV, key);
// check if the information you input is correct
int index = 0;
//check if it is the first one
if(oldUserInfor[0].equals(username) && oldUserInfor[1].equals(password) ){
if (oldUserInfor[2].equals(domainname)){
System.out.println("the information you input does exit in the original file, now deleting");
String[] result = new String[oldUserInfor.length-3];
System.arraycopy(oldUserInfor, 3, result, 0, result.length);
oldNUM--;
byte[] newNum = ArrayMaster.intToBytes(oldNUM);
byte[] newIV = Encryption.get_IV(16);
byte[] newUser = Encryption.enc_alluser(result,newIV,key);
byte[] newRoot = Encryption.merkle_tree_hashing(newUser);
byte[] newAll = ArrayMaster.combine2array(newNum, newUser);
fileMaster.rm_content_fm_passfile();
fileMaster.write_everything_into_password_file(newRoot, newIV, newAll);
System.out.println("deleted!!");
continues();
}
}
// check the rest
for(int i = 3; i < oldUserInfor.length;i+=3){
if(oldUserInfor[i].equals(username) && oldUserInfor[i+1].equals(password) ){
if (oldUserInfor[i+2].equals(domainname)){
System.out.println("the information you input does exit in the original file, now deleting");
index = i;
}
}
}
//we have already checked the first one, hence we don't the index should be 0 if there is a match
if(index !=0 ){
String[] left = new String[index];
String[] right = new String[oldUserInfor.length-(index+3)];
System.arraycopy(oldUserInfor, 0, left, 0, left.length);
System.arraycopy(oldUserInfor, (index+3), right, 0, right.length);
String[] result = ArrayMaster.combine2StingArray(left,right);
oldNUM--;
byte[] newNum = ArrayMaster.intToBytes(oldNUM);
byte[] newIV = Encryption.get_IV(16);
byte[] newUser = Encryption.enc_alluser(result,newIV,key);
byte[] newRoot = Encryption.merkle_tree_hashing(newUser);
byte[] newAll = ArrayMaster.combine2array(newNum, newUser);
fileMaster.rm_content_fm_passfile();
fileMaster.write_everything_into_password_file(newRoot, newIV, newAll);
System.out.println("deleted!!");
continues();
}else{
System.out.println("URGE ACCOUNT DOES NOT EXIT!\n");
System.out.println("what else you wanna do?\n");
continues();
}
}
private static void change_account() throws NoSuchAlgorithmException, IOException, Exception {
System.out.println("Please enter the username, that you wanna change");
Scanner input1 = new Scanner(System.in);
String username = input1.nextLine();
System.out.println("Please enter the password, that you wanna change");
Scanner input2 = new Scanner(System.in);
String password = input2.nextLine();
System.out.println("Please enter the domain name, that you wanna change");
Scanner input3 = new Scanner(System.in);
String domainname = input3.nextLine();
byte oldIV[] = fileMaster.read_IV_fm_passfile();
byte key[] = Encryption.KeyGen();
byte Num[] = fileMaster.read_Num_of_user_fm_passfile();
int NUM = ArrayMaster.Convert_4_byte_byteArray_toInt(Num);
byte oldUser[] = fileMaster.read_all_users_infor_fm_passfile();
String UserInfor[] = Encryption.collection(NUM, oldUser, oldIV, key);
int index = 0;
//check if it is the first one matches
if(UserInfor[0].equals(username) && UserInfor[1].equals(password) ){
if (UserInfor[2].equals(domainname)){
System.out.println("The information you input is correct");
System.out.println("Please enter the password, that you wanna change");
Scanner input4 = new Scanner(System.in);
String newpassword = input4.nextLine();
UserInfor[1] = newpassword;
byte[] newIV = Encryption.get_IV(16);
byte[] newUser = Encryption.enc_alluser(UserInfor,newIV,key);
byte[] newRoot = Encryption.merkle_tree_hashing(newUser);
byte[] newAll = ArrayMaster.combine2array(Num, newUser);
fileMaster.rm_content_fm_passfile();
fileMaster.write_everything_into_password_file(newRoot, newIV, newAll);
System.out.println("changed!!");
continues();
}
}
// check the rest
for(int i = 3; i < UserInfor.length;i+=3){
if(UserInfor[i].equals(username) && UserInfor[i+1].equals(password) ){
if (UserInfor[i+2].equals(domainname)){
System.out.println("The information you input is correct");
System.out.println("Please enter the password, that you wanna change");
Scanner input5 = new Scanner(System.in);
String newpasswords = input5.nextLine();
UserInfor[i+1] = newpasswords;
byte[] newIVs = Encryption.get_IV(16);
byte[] newUsers = Encryption.enc_alluser(UserInfor,newIVs,key);
byte[] newRoots = Encryption.merkle_tree_hashing(newUsers);
byte[] newAlls = ArrayMaster.combine2array(Num, newUsers);
fileMaster.rm_content_fm_passfile();
fileMaster.write_everything_into_password_file(newRoots, newIVs, newAlls);
System.out.println("changed!!");
continues();
}
System.out.println("URGE ACCOUNT DOES NOT EXIT!\n");
System.out.println("what else you wanna do?\n");
continues();
}
}
}
private static void get_passward() throws NoSuchAlgorithmException, IOException, Exception {
System.out.println("Please enter the domain name, so that you can see the correspondening username and password");
Scanner input3 = new Scanner(System.in);
String domainname = input3.nextLine();
byte IV[] = fileMaster.read_IV_fm_passfile();
byte key[] = Encryption.KeyGen();
byte Num[] = fileMaster.read_Num_of_user_fm_passfile();
int NUM = ArrayMaster.Convert_4_byte_byteArray_toInt(Num);
byte User[] = fileMaster.read_all_users_infor_fm_passfile();
String UserInfor[] = Encryption.collection(NUM, User, IV, key);
int check = 0;
System.out.println("username password domainame");
for(int i = 0; i<UserInfor.length;i+=3){
System.out.print(UserInfor[i] + " " +UserInfor[i+1]+ " " +UserInfor[i+2] +"\n");
if(UserInfor[i+2].equals(domainname)){
System.out.println("what should be displayed");
System.out.print(UserInfor[i] + " " +UserInfor[i+1] +"\n");
check++;
}
}
if(check == 0){
System.out.println("URGE ACCOUNT DOES NOT EXIT!\n");
System.out.println("what else you wanna do?\n");
continues();
}
continues();
}
// continus to access more methods when you done one method;
private static void continues() throws NoSuchAlgorithmException, IOException, Exception{
System.out.println("Enter y for yes to do more option, or n for no to exit");
Scanner input = new Scanner(System.in);
String option = input.nextLine();
if("y".equals(option)){
run();
}else if("n".equals(option)){
exit();
}
else{
System.out.println("These is no such an option for " + option);
continues();
}
}
private static void exit() {System.exit(0);}
private static void run() throws NoSuchAlgorithmException, IOException, Exception {
System.out.println("You can enter a number to do following options");
System.out.println("enter 1 to register_account");
System.out.println("enter 2 to check_integraty");
System.out.println("enter 3 to delete_account");
System.out.println("enter 4 to change_account");
System.out.println("enter 5 to get_passward");
System.out.println("enter 6 to exit");
Scanner input = new Scanner(System.in);
String option = input.nextLine();
if("1".equals(option)){
register_account();
}
else if("2".equals(option)){
check_integraty();
}
else if("3".equals(option)){
delete_account();
}
else if("4".equals(option)){
change_account();
}
else if("5".equals(option)){
get_passward();
}
else if("6".equals(option)){
exit();
}
else{
System.out.println("the is no such an option for option" + option);
run();
}
}
// the following code is main method
public static void main(String[] args) throws IOException, NoSuchProviderException, NoSuchAlgorithmException, Exception {
String result = fileMaster.AutofileSearching();
if("all missing".equals(result)){
System.out.println("You have not register yet, now creating passwd_file and master_passwd in the current folder");
System.out.println("Please create the master passward: ");
Scanner input = new Scanner(System.in);
String master_password_string = input.nextLine();
byte[] IV_master_password = Encryption.get_IV(32);
byte[] master_password_hashed = Encryption.set_master_passwd(master_password_string, IV_master_password);
File passfile = new File(fileMaster.folderpath+"passwd_file.txt");
File massfile = new File(fileMaster.folderpath+"master_passwd.txt");
// code here is for creating those 2 files
passfile.createNewFile();
massfile.createNewFile();
//now write the byte[] for iv and write the byte[] for master_password hashed with iv into masster_passwd.txt
fileMaster.write_everything_into_master_file(IV_master_password, master_password_hashed);
System.out.println("Files Created, now please run again to do further option( e.g. to register)");
exit();
}
// now if there exit those 2 files, we do following
else{
Scanner input = new Scanner(System.in);
System.out.println("Please enter the master passward: ");
String new_master_password_string = input.nextLine();
Path path = Paths.get(fileMaster.folderpath+"master_passwd.txt");
byte[] data = Files.readAllBytes(path); // it includes iv[] and the master[] that hashed by iv[]
byte[] IV_Orginary = new byte[32];
byte[] master_Orginary = new byte[64];
for (int i = 0; i<IV_Orginary.length; i++){
IV_Orginary[i] = data[i]; // loop the iv part from data[]
}
for (int i = 32; i<data.length; i++){
master_Orginary[i-32] = data[i]; //loop the master[] from data[]
}
byte[] new_master = Encryption.set_master_passwd(new_master_password_string, IV_Orginary); // now I hash the string with orginary iv[]
for(int i = 0; i<new_master.length;i++ ){
if(master_Orginary[i] != new_master[i]){
System.out.println(); // if there exit any byte that is different between 2 mas[] then we fail
System.out.println("WRONG MASSTER PASSWORD");
System.exit(0);
}
}
System.out.println("The master password is correct");
TheMas = new_master_password_string; //after I passed the Master_password check I can use the value
String check_integraty_result = check_integraty(); // if it passed check_integraty
if("success".equals(check_integraty_result)){
System.out.println("The check_integraty passed");
System.out.println("welcome to the main menu");
run();
}
}
}
}
Comments