public boolean upload( String sourceFile, String destFile, String group, UserToken token, Key key, int keyNum) { if (destFile.charAt(0) != '/') { destFile = "/" + destFile; } try { FileInputStream fis = new FileInputStream(sourceFile); File encryptFile = new File(sourceFile + "_encrypt"); encryptFile.createNewFile(); FileOutputStream fos = new FileOutputStream(encryptFile); // Initial Vector must be 16 bytes byte[] initialVector = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; IvParameterSpec ivs = new IvParameterSpec(initialVector); byte[] buf = new byte[1024]; Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); cipher.init(Cipher.ENCRYPT_MODE, key, ivs); byte[] cipherBytes; // create a new local encrypted file do { buf = new byte[1024]; int n = fis.read(buf); if (n > 0) { System.out.printf("."); } else if (n < 0) { System.out.println("Read error"); } cipherBytes = cipher.doFinal(buf); fos.write(cipherBytes); } while (fis.available() > 0); System.out.println(); // send encrypted file to server Envelope message = null, env = null; // Tell the server to return the member list message = new Envelope("UPLOADF"); message.addObject(destFile); message.addObject(group); message.addObject(token); message.addObject(keyNum); message.addObject(initialVector); String concat = destFile + group + token.toString() + keyNum + "UPLOADF" + nonce; // concatinates all of the objects in envelope byte[] hasharray = concat.getBytes(); // turn the concat into a byte array Mac mac = Mac.getInstance("HmacSHA1"); mac.init(HMACkey); mac.update(hasharray); String stringhash = new String(mac.doFinal(), "UTF8"); // turn the hash into a string for easy comparision! message.addObject(stringhash); message.addObject(nonce); nonce++; byte[] messageBytes = Envelope.toByteArray(message); // Encrypt envelope w/ AES cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, AESkey); cipherBytes = cipher.doFinal(messageBytes); output.writeObject(cipherBytes); byte[] responseCipherBytes = (byte[]) input.readObject(); // if response isnt ready it should check whether it was forged // Decrypt response cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, AESkey); byte[] responseBytes = cipher.doFinal(responseCipherBytes); env = Envelope.getEnvelopefromBytes(responseBytes); if (env.getMessage().equals("READY")) { System.out.printf("Meta data upload successful\n"); } else if ((Integer) env.getObjContents().get(1) == nonce) { String hash = (String) env.getObjContents().get(0); concat = env.getMessage() + nonce; // reconstructs the hash hasharray = concat.getBytes(); mac = Mac.getInstance("HmacSHA1"); File HASHfile = new File("FHASHKey.bin"); fis = new FileInputStream(HASHfile); ObjectInputStream ois = new ObjectInputStream(fis); Key HMACkey = (Key) ois.readObject(); mac.init(HMACkey); mac.update(hasharray); String newhash = new String(mac.doFinal(), "UTF8"); nonce++; // check hashes for equality if (hash.equals(newhash) != true) { System.out.println("HASH EQUALITY FAIL2, disconnecting for your own safety"); disconnect(); return false; } } else { System.out.println("Nonce FAIL UPLOADF"); disconnect(); return false; } // If server indicates success, return the member list FileInputStream encryptFIS = new FileInputStream(encryptFile); do { if ((Integer) env.getObjContents().get(1) == nonce) { buf = new byte[1024]; if (!env.getMessage().equals("READY")) { System.out.printf("Server error: %s\n", env.getMessage()); return false; } String hash = (String) env.getObjContents().get(0); concat = env.getMessage() + nonce; // reconstructs the hash hasharray = concat.getBytes(); mac = Mac.getInstance("HmacSHA1"); File HASHfile = new File("FHASHKey.bin"); fis = new FileInputStream(HASHfile); ObjectInputStream ois = new ObjectInputStream(fis); Key HMACkey = (Key) ois.readObject(); mac.init(HMACkey); mac.update(hasharray); String newhash = new String(mac.doFinal(), "UTF8"); nonce++; ois.close(); // check hashes for equality if (hash.equals(newhash) != true) { System.out.println("HASH EQUALITY FAIL3, disconnecting for your own safety"); disconnect(); return false; } message = new Envelope("CHUNK"); int n = encryptFIS.read(buf); // can throw an IOException if (n > 0) { System.out.printf("."); } else if (n < 0) { System.out.println("Read error"); return false; } message.addObject(buf); message.addObject(new Integer(n)); concat = n + "CHUNK" + nonce; // concatinates all of the objects in envelope hasharray = concat.getBytes(); // turn the concat into a byte array mac = Mac.getInstance("HmacSHA1"); mac.init(HMACkey); mac.update(hasharray); stringhash = new String( mac.doFinal(), "UTF8"); // turn the hash into a string for easy comparision! message.addObject(stringhash); message.addObject(nonce); nonce++; messageBytes = Envelope.toByteArray(message); // Encrypt envelope w/ AES cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, AESkey); cipherBytes = cipher.doFinal(messageBytes); System.out.println("Concatsent" + concat); output.writeObject( cipherBytes); /////////////////////////////////////////// // HERE///////////////////////////////// responseCipherBytes = (byte[]) input.readObject(); // Decrypt response cipher.init(Cipher.DECRYPT_MODE, AESkey); responseBytes = cipher.doFinal(responseCipherBytes); env = Envelope.getEnvelopefromBytes(responseBytes); } else { System.out.println("Nonce FAIL UPLOADF"); disconnect(); return false; } } while (encryptFIS.available() > 0); encryptFIS.close(); // If server indicates success, return the member list if (env.getMessage().compareTo("READY") == 0 && (Integer) env.getObjContents().get(1) == nonce) { nonce++; message = new Envelope("EOF"); concat = "EOF" + nonce; // concatinates all of the objects in envelope hasharray = concat.getBytes(); // turn the concat into a byte array mac = Mac.getInstance("HmacSHA1"); mac.init(HMACkey); mac.update(hasharray); stringhash = new String(mac.doFinal(), "UTF8"); // turn the hash into a string for easy comparision! message.addObject(stringhash); message.addObject(nonce); System.out.println(nonce); nonce++; messageBytes = Envelope.toByteArray(message); // Encrypt envelope w/ AES cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, AESkey); cipherBytes = cipher.doFinal(messageBytes); output.writeObject(cipherBytes); responseCipherBytes = (byte[]) input.readObject(); // Decrypt response cipher.init(Cipher.DECRYPT_MODE, AESkey); responseBytes = cipher.doFinal(responseCipherBytes); env = Envelope.getEnvelopefromBytes(responseBytes); if (env.getMessage().compareTo("OK") == 0 && (Integer) env.getObjContents().get(1) == nonce) { System.out.printf("\nFile data upload successful\n"); } else if ((Integer) env.getObjContents().get(1) != nonce) { System.out.println("Nonce FAIL UPLOADF"); disconnect(); return false; } else { System.out.printf("\nUpload failed: %s\n", env.getMessage()); return false; } } else if ((Integer) env.getObjContents().get(1) != nonce) { System.out.println("Nonce FAIL UPLOADF"); disconnect(); return false; } else { System.out.printf("Upload failed: %s\n", env.getMessage()); return false; } } catch (Exception e1) { System.err.println("Error: " + e1.getMessage()); e1.printStackTrace(System.err); return false; } return true; }
public static void main(String[] args) throws Exception { String digestType = args[0]; String digestFile = args[1]; Vector<String> digestListFiles = new Vector<String>(); Vector<byte[]> calcDigests = new Vector<byte[]>(); BufferedReader reader = null; byte[] fileContent; int i; for (i = 2; i < args.length; i++) { digestListFiles.add(args[i]); } // le os arquivos e calcula o digest de seus conteudos. for (i = 0; i < digestListFiles.size(); i++) { File file = new File(digestListFiles.get(i)); fileContent = readFile(file); MessageDigest messageDigest; try { messageDigest = MessageDigest.getInstance(digestType); } catch (Exception e) { System.out.println("Inexistant cryptography algorithm given!"); return; } messageDigest.update(fileContent); calcDigests.add(messageDigest.digest()); } File digestListFile = new File(digestFile); // verifica se o arquivo existe. // caso nao exista, cria um novo. if (!digestListFile.exists()) digestListFile.createNewFile(); // lista dos arquivos ja lidos Vector<String> fileNames = new Vector<String>(); // lista do tipos dos digest dos arquivos Vector<String> fileTypes = new Vector<String>(); // lista dos digest dos conteudos dos arquivos Vector<String> fileDigests = new Vector<String>(); try { reader = new BufferedReader(new FileReader(digestListFile)); String line; String[] splitLine; while ((line = reader.readLine()) != null) { splitLine = line.split(" "); fileNames.add(splitLine[0]); // le o nome do arquivo fileTypes.add(splitLine[1]); // le o tipo do digest fileDigests.add(splitLine[2]); // le o digest em hex } } catch (IOException e) { System.out.println("Problems reading digest file! " + e.getStackTrace().toString()); } STATUS status; int pos; for (i = 0; i < digestListFiles.size(); i++) { // procura pos = find(fileNames, digestListFiles.get(i), fileTypes, digestType); if (pos != -1) { // achou // verifica se o conteudo eh igual if (fileDigests.get(pos).contentEquals(calcHex(calcDigests.get(i)))) { status = STATUS.OK; // conteudo igual } else { status = STATUS.NOTOK; // conteudo diferente } } else { // nao achou! // insere no arquivo writeToEOF( digestListFiles.get(i) + " " + digestType + " " + calcHex(calcDigests.get(i)) + "\n", digestListFile); fileNames.add(digestListFiles.get(i)); fileTypes.add(digestType); fileDigests.add(calcHex(calcDigests.get(i))); status = STATUS.NOTFOUND; } System.out.println( digestListFiles.get(i) + " " + digestType + " " + calcHex(calcDigests.get(i)) + " (" + status.toString() + ")"); } }
public boolean download( String sourceFile, String destFile, UserToken token, HashMap<String, ArrayList<Key>> keys) { try { destFile = "." + destFile; if (sourceFile.charAt(0) == '/') { sourceFile = sourceFile.substring(1); } File file = new File(destFile); if (!file.exists()) { file.createNewFile(); FileOutputStream fos = new FileOutputStream(file); Envelope env = new Envelope("DOWNLOADF"); // Success env.addObject(sourceFile); env.addObject(token); String concat = sourceFile + token.toString() + "DOWNLOADF" + nonce; // concatinates all of the objects in envelope byte[] hasharray = concat.getBytes(); // turn the concat into a byte array Mac mac = Mac.getInstance("HmacSHA1"); mac.init(HMACkey); mac.update(hasharray); String stringhash = new String(mac.doFinal(), "UTF8"); // turn the hash into a string for easy comparision! env.addObject(stringhash); env.addObject(nonce); nonce++; byte[] envBytes = Envelope.toByteArray(env); // Encrypt envelope w/ AES Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, AESkey); byte[] cipherBytes = cipher.doFinal(envBytes); output.writeObject(cipherBytes); // here in download byte[] responseCipherBytes = (byte[]) input.readObject(); // Decrypt response cipher.init(Cipher.DECRYPT_MODE, AESkey); byte[] responseBytes = cipher.doFinal(responseCipherBytes); env = Envelope.getEnvelopefromBytes(responseBytes); ShareFile sf = (ShareFile) env.getObjContents().get(2); int keyNum = sf.getKeyNum(); ArrayList<Key> groupKeys = keys.get(sf.getGroup()); Key key = groupKeys.get(keyNum); byte[] initialVector = sf.getIV(); IvParameterSpec ivs = new IvParameterSpec(initialVector); byte[] decryptBuf = new byte[1024]; while (env.getMessage().compareTo("CHUNK") == 0 && (Integer) env.getObjContents().get(4) == nonce) { String hash = (String) env.getObjContents().get(3); concat = (Integer) env.getObjContents().get(1) + env.getMessage() + nonce; // reconstructs the hash System.out.println("Concat:" + concat); hasharray = concat.getBytes(); mac = Mac.getInstance("HmacSHA1"); File HASHfile = new File("FHASHKey.bin"); FileInputStream fis = new FileInputStream(HASHfile); ObjectInputStream ois = new ObjectInputStream(fis); HMACkey = (Key) ois.readObject(); mac.init(HMACkey); mac.update(hasharray); String newhash = new String(mac.doFinal(), "UTF8"); nonce++; // check hashes for equality if (hash.equals(newhash) != true) { System.out.println("HASH EQUALITY FAIL1"); disconnect(); return false; } else { decryptBuf = new byte[1024]; System.out.println("env.getMessage: " + env.getMessage()); cipher = Cipher.getInstance("AES/CBC/NoPadding"); cipher.init(Cipher.DECRYPT_MODE, key, ivs); decryptBuf = cipher.doFinal((byte[]) env.getObjContents().get(0)); // Write encrypted file to disk fos.write(decryptBuf); System.out.printf("."); env = new Envelope("DOWNLOADF"); // Success concat = env.getMessage() + nonce; // concatinates all of the objects in envelope hasharray = concat.getBytes(); // turn the concat into a byte array mac = Mac.getInstance("HmacSHA1"); mac.init(HMACkey); mac.update(hasharray); stringhash = new String( mac.doFinal(), "UTF8"); // turn the hash into a string for easy comparision! env.addObject(stringhash); env.addObject(nonce); nonce++; envBytes = Envelope.toByteArray(env); // Encrypt envelope w/ AES cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, AESkey); cipherBytes = cipher.doFinal(envBytes); output.writeObject(cipherBytes); responseCipherBytes = (byte[]) input.readObject(); // Decrypt response cipher.init(Cipher.DECRYPT_MODE, AESkey); responseBytes = cipher.doFinal(responseCipherBytes); env = Envelope.getEnvelopefromBytes(responseBytes); } } fos.close(); if (env.getMessage().compareTo("EOF") == 0 && (Integer) env.getObjContents().get(1) == nonce) { String hash = (String) env.getObjContents().get(0); concat = env.getMessage() + nonce; // reconstructs the hash hasharray = concat.getBytes(); mac = Mac.getInstance("HmacSHA1"); File HASHfile = new File("FHASHKey.bin"); FileInputStream fis = new FileInputStream(HASHfile); ObjectInputStream ois = new ObjectInputStream(fis); HMACkey = (Key) ois.readObject(); mac.init(HMACkey); mac.update(hasharray); String newhash = new String(mac.doFinal(), "UTF8"); if (hash.equals(newhash) != true) // check hashes for equality { System.out.println("HASH EQUALITY FAIL2"); disconnect(); } fos.close(); System.out.printf("\nTransfer successful file %s\n", sourceFile); nonce++; env = new Envelope("OK"); // Success concat = env.getMessage() + nonce; // concatinates all of the objects in envelope hasharray = concat.getBytes(); // turn the concat into a byte array mac = Mac.getInstance("HmacSHA1"); mac.init(HMACkey); mac.update(hasharray); stringhash = new String( mac.doFinal(), "UTF8"); // turn the hash into a string for easy comparision! env.addObject(stringhash); env.addObject(nonce); nonce++; envBytes = Envelope.toByteArray(env); // Encrypt envelope w/ AES cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, AESkey); cipherBytes = cipher.doFinal(envBytes); output.writeObject(cipherBytes); } else if ((Integer) env.getObjContents().get(1) != nonce) { System.out.println("Nonce FAIL DOWNLOADF"); disconnect(); return false; } else { System.out.printf("Error reading file %s (%s)\n", sourceFile, env.getMessage()); file.delete(); return false; } } else { System.out.printf("Error couldn't create file %s\n", destFile); return false; } } catch (InvalidAlgorithmParameterException ex) { Logger.getLogger(FileClient.class.getName()).log(Level.SEVERE, null, ex); } catch (IllegalBlockSizeException ex) { Logger.getLogger(FileClient.class.getName()).log(Level.SEVERE, null, ex); System.out.println(1); } catch (BadPaddingException ex) { Logger.getLogger(FileClient.class.getName()).log(Level.SEVERE, null, ex); System.out.println(2); } catch (InvalidKeyException ex) { Logger.getLogger(FileClient.class.getName()).log(Level.SEVERE, null, ex); System.out.println(3); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(FileClient.class.getName()).log(Level.SEVERE, null, ex); System.out.println(4); } catch (NoSuchPaddingException ex) { Logger.getLogger(FileClient.class.getName()).log(Level.SEVERE, null, ex); System.out.println(5); } catch (IOException e1) { System.out.printf("Error couldn't create file %s\n", destFile); return false; } catch (ClassNotFoundException e1) { e1.printStackTrace(System.err); } return true; }
public boolean connect(String username, String weakSecret, final String server, final int port) { System.out.println("attempting to connect"); try { sock = new Socket(); sock.connect(new InetSocketAddress(server, port)); output = new ObjectOutputStream(sock.getOutputStream()); input = new ObjectInputStream(sock.getInputStream()); output.writeObject(username); // do DH exchange and agree on starting message index try { if (weakSecret != null) // group server connect { HashMap<String, SecretKey> secretKeys = DHKeyExchange.generateSecretKeyWithWeakSecret(username, weakSecret, input, output); if (secretKeys == null) throw new Exception("Unable to verify server"); encryptionKey = secretKeys.get("encryptionKey"); signingKey = secretKeys.get("signingKey"); } else // file server connect { PublicKey fileServerPublicKey = (PublicKey) input.readObject(); // read in public key File savedKeys = new File("savedkeys.bin"); ArrayList<PublicKey> knownKeys = new ArrayList<PublicKey>(); if (savedKeys.exists()) { ObjectInputStream in = new ObjectInputStream(new FileInputStream(savedKeys)); knownKeys = (ArrayList<PublicKey>) in.readObject(); } if (!knownKeys.contains(fileServerPublicKey)) // prompt the user to verify the key { MessageDigest sha = MessageDigest.getInstance("SHA-1"); byte[] digest = sha.digest(fileServerPublicKey.getEncoded()); System.out.println("RSA key fingerprint is " + getFingerprint(digest)); System.out.println( "Please verify this is correct by contacting the file server owner."); System.out.println( "Do you want to add this key to your list of saved servers? (yes/no)"); Scanner scanner = new Scanner(System.in); String answer = scanner.nextLine(); if (answer.toLowerCase().equals("yes")) { knownKeys.add(fileServerPublicKey); savedKeys.delete(); savedKeys.createNewFile(); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(savedKeys)); out.writeObject(knownKeys); out.flush(); out.close(); output.writeObject("yes"); } else { output.writeObject("no"); System.out.println("Exiting"); System.exit(0); } } else // accpet the key without prompt output.writeObject("yes"); generateRSAKeypair(); output.writeObject(publicKey); HashMap<String, SecretKey> secretKeys = DHKeyExchange.generateSecretKeySignedExchange( input, output, privateKey, fileServerPublicKey); if (secretKeys == null) throw new Exception("Unable to verify server"); encryptionKey = secretKeys.get("encryptionKey"); signingKey = secretKeys.get("signingKey"); } encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); MessageDigest sha = MessageDigest.getInstance("SHA-1"); byte[] key = sha.digest(encryptionKey.getEncoded()); key = Arrays.copyOf(key, 16); // use only first 128 bit SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); encryptCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, new IvParameterSpec(ivBytes)); decryptCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(ivBytes)); BigInteger R = new BigInteger(128, new SecureRandom()); output.writeObject(encryptCipher.doFinal(R.toByteArray())); BigInteger start = new BigInteger(decryptCipher.doFinal((byte[]) input.readObject())); if (start.compareTo(R) < 0) throw new Exception("Invalid message index from server"); else messageIndex = start.add(BigInteger.ONE); } catch (Exception ex) { System.out.println("Failed to connect: " + ex.getMessage()); // if anything fails, we are not connected sock = null; return false; } } catch (IOException ex) { return false; } return true; }