/*  Ejemplo de uso de funciones de resumen Hash
   *  carga el fichero que recibe como parametro y genera el resumen
   */
  public static void main(String[] args) throws Exception {
    // Comprobar argumentos
    if (args.length != 1) {
      mensajeAyuda();
      System.exit(1);
    }

    /* Cargar "provider" (sólo si no se usa el que viene por defecto) */
    Security.addProvider(new BouncyCastleProvider()); // Usa provider BC

    /* Crear función resumen */
    // MessageDigest messageDigest = MessageDigest.getInstance("MD5"); // Usa MD5
    MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); // Usar SHA-1

    /* Leer fichero de 1k en 1k y pasar fragmentos leidos a la funcion resumen */
    byte[] buffer = new byte[1000];
    int leidos = in.read(buffer, 0, 1000);
    while (leidos != -1) {
      messageDigest.update(buffer); // Pasa texto claro a la función resumen
      leidos = in.read(buffer, 0, 1000);
    }
    in.close();

    byte[] resumen = messageDigest.digest(); // Completar el resumen

    // Mostrar resumen
    System.out.println("RESUMEN:");
    mostrarBytes(resumen);
    System.out.println();
  }
  public void run() {
    try {
      ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
      ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());

      BigInteger bg = dhSpec.getG();
      BigInteger bp = dhSpec.getP();
      oos.writeObject(bg);
      oos.writeObject(bp);

      KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");
      kpg.initialize(1024);
      KeyPair kpa = (KeyPair) ois.readObject();
      KeyAgreement dh = KeyAgreement.getInstance("DH");
      KeyPair kp = kpg.generateKeyPair();

      oos.writeObject(kp);

      dh.init(kp.getPrivate());
      Key pk = dh.doPhase(kpa.getPublic(), true);

      MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
      byte[] rawbits = sha256.digest(dh.generateSecret());

      Cipher c = Cipher.getInstance(CIPHER_MODE);
      SecretKey key = new SecretKeySpec(rawbits, 0, 16, "AES");
      byte ivbits[] = (byte[]) ois.readObject();
      IvParameterSpec iv = new IvParameterSpec(ivbits);
      c.init(Cipher.DECRYPT_MODE, key, iv);

      Mac m = Mac.getInstance("HmacSHA1");
      SecretKey mackey = new SecretKeySpec(rawbits, 16, 16, "HmacSHA1");
      m.init(mackey);

      byte ciphertext[], cleartext[], mac[];
      try {
        while (true) {
          ciphertext = (byte[]) ois.readObject();
          mac = (byte[]) ois.readObject();
          if (Arrays.equals(mac, m.doFinal(ciphertext))) {
            cleartext = c.update(ciphertext);
            System.out.println(ct + " : " + new String(cleartext, "UTF-8"));
          } else {
            // System.exit(1);
            System.out.println(ct + "error");
          }
        }
      } catch (EOFException e) {
        cleartext = c.doFinal();
        System.out.println(ct + " : " + new String(cleartext, "UTF-8"));
        System.out.println("[" + ct + "]");
      } finally {
        if (ois != null) ois.close();
        if (oos != null) oos.close();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }