Пример #1
0
  private static void saveKey(String fileName, Key key) {
    try {
      FileOutputStream fos = new FileOutputStream(new File(fileName));
      ObjectOutputStream oos = new ObjectOutputStream(fos);

      oos.writeObject(key);
      oos.flush();
      fos.close();

    } catch (IOException e) {
      e.printStackTrace();
    }
  }
Пример #2
0
  /**
   * Sends the specified file to the client. File must exist or client and server threads will hang
   * indefinitely. Generates a session key to encrypt the file over transfer; session key is
   * encrypted using the client's public (asymmetric) key.
   *
   * @param aFile The name or path of the file to send.
   * @throws IOException Error reading from socket.
   */
  private void sendFile(String aFile) throws IOException {
    try {
      // get client public key
      ObjectInputStream clientPubIn = new ObjectInputStream(connectedSocket.getInputStream());
      PublicKey clientPublicKey = (PublicKey) clientPubIn.readObject();

      // generate key string and send to client using their public key encrypted with RSA
      // (asymmetric)
      String keyString = generateKeyString();
      Cipher keyCipher = Cipher.getInstance("RSA");
      keyCipher.init(Cipher.ENCRYPT_MODE, clientPublicKey);
      SealedObject sealedKeyString = new SealedObject(keyString, keyCipher);
      ObjectOutputStream testOut = new ObjectOutputStream(outToClient);
      testOut.writeObject(sealedKeyString);
      testOut.flush();

      // generate key spec from keyString
      SecretKeySpec keySpec = new SecretKeySpec(keyString.getBytes(), "DES");

      // set up encryption
      Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
      cipher.init(Cipher.ENCRYPT_MODE, keySpec);
      CipherOutputStream cipherOut = new CipherOutputStream(outToClient, cipher);

      // send file
      byte[] fileBuffer = new byte[BUFFER_SIZE];
      InputStream fileReader = new BufferedInputStream(new FileInputStream(aFile));
      int bytesRead;
      while ((bytesRead = fileReader.read(fileBuffer)) != EOF) {
        cipherOut.write(fileBuffer, 0, bytesRead);
      }
      cipherOut.flush();
      cipherOut.close();
      disconnect();
    } catch (NoSuchPaddingException nspe) {
      System.out.println("No such padding.");
    } catch (NoSuchAlgorithmException nsae) {
      System.out.println("Invalid algorithm entered");
    } catch (ClassNotFoundException cnfe) {
      System.out.println("Class not found.");
    } catch (InvalidKeyException ike) {
      System.out.println("Invalid key used for file encryption.");
    } catch (FileNotFoundException fnfe) {
      System.out.println("Invalid file entered.");
      return;
    } catch (IllegalBlockSizeException ibse) {
      System.out.println("Illegal block size used for encryption.");
    }
  }
Пример #3
0
  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;
  }