예제 #1
0
  // creates an crypto object that uses PBE based DES encryption.... and yeah, DES is horrid, but
  // its what we've got right now
  Encrypter(String password) {
    try {
      // key... like the one I don't to the office... which means I get locked out post 5
      KeySpec keySpec = new PBEKeySpec(password.toCharArray());
      SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);

      encryptionCipher = Cipher.getInstance(key.getAlgorithm());
      decryptionCipher = Cipher.getInstance(key.getAlgorithm());
      AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);

      encryptionCipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
      decryptionCipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
    } catch (Exception e) {
      System.out.println("Encryption Object Error: " + e);
    }
  }
예제 #2
0
 public static byte[] func_75895_a(String p_75895_0_, PublicKey p_75895_1_, SecretKey p_75895_2_) {
   try {
     return func_75893_a(
         "SHA-1",
         new byte[][] {
           p_75895_0_.getBytes("ISO_8859_1"), p_75895_2_.getEncoded(), p_75895_1_.getEncoded()
         });
   } catch (UnsupportedEncodingException unsupportedencodingexception) {
     unsupportedencodingexception.printStackTrace();
   }
   return null;
 }
예제 #3
0
 /**
  * Reads the raw data from the input File, encrypts and saves its contents to the output File, and
  * then save the raw data of the SecretKey used to the SecretKey File.
  *
  * @param input the File to be read and encrypted
  * @param output the File the encrypted data will be saved to
  * @param keyFile the File the SecretKey data will be saved to
  * @throws InvalidKeyException if the given key is inappropriate for initializing this cipher, or
  *     if this cipher is being initialized for decryption and requires algorithm parameters that
  *     cannot be determined from the given key, or if the given key has a keysize that exceeds the
  *     maximum allowable keysize (as determined from the configured jurisdiction policy files).
  * @throws IOException if any of the files do not exist, are a directory rather than a regular
  *     file, or for some other reason cannot be opened for reading or if an I/O error occurs.
  * @throws IllegalBlockSizeException if the cipher is a block cipher, no padding has been
  *     requested (only in encryption mode), and the total input length of the data processed by
  *     this cipher is not a multiple of block size; or if this encryption algorithm is unable to
  *     process the input data provided.
  * @throws BadPaddingException if the cipher is in decryption mode, and (un)padding has been
  *     requested, but the decrypted data is not bounded by the appropriate padding bytes
  */
 public void encrypt(File input, File output, File keyFile)
     throws InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException {
   if (debug) {
     System.out.println("Initializing encryption...");
   }
   cipher.init(Cipher.ENCRYPT_MODE, key);
   FileInputStream fis = null;
   try {
     fis = new FileInputStream(input);
     data = new byte[(int) input.length()];
     if (debug) {
       System.out.println("Reading data...");
     }
     fis.read(data);
   } finally {
     if (fis != null) {
       fis.close();
     }
   }
   if (debug) {
     System.out.println("Encrypting data...");
   }
   data = cipher.doFinal(data);
   FileOutputStream fos = null;
   try {
     fos = new FileOutputStream(output);
     if (debug) {
       System.out.println("Saving data...");
     }
     fos.write(data);
   } finally {
     if (fos != null) {
       fos.close();
     }
   }
   if (debug) {
     System.out.println("Saving key...");
   }
   data = key.getEncoded();
   fos = null;
   try {
     fos = new FileOutputStream(keyFile);
     fos.write(data);
   } finally {
     if (fos != null) {
       fos.close();
     }
   }
   if (debug) {
     System.out.println("Encryption complete!");
   }
   data = null;
 }
  public static void main(String[] args) throws Exception {
    // prompt user to enter a port number

    System.out.print("Enter the port number: ");
    Scanner scan = new Scanner(System.in);
    int port = scan.nextInt();
    scan.nextLine();
    System.out.print("Enter the host name: ");
    String hostName = scan.nextLine();

    // Initialize a key pair generator with the SKIP parameters we sepcified, and genrating a pair
    // This will take a while: 5...15 seconrds

    System.out.println("Generating a Diffie-Hellman keypair: ");
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");
    kpg.initialize(PARAMETER_SPEC);
    KeyPair keyPair = kpg.genKeyPair();
    System.out.println("key pair has been made...");

    // one the key pair has been generated, we want to listen on
    // a given port for a connection to come in
    // once we get a connection, we will get two streams, One for input
    // and one for output
    // open a port and wait for a connection

    ServerSocket ss = new ServerSocket(port);
    System.out.println("Listeining on port " + port + " ...");
    Socket socket = ss.accept();

    // use to output and input primitive data type

    DataOutputStream out = new DataOutputStream(socket.getOutputStream());

    // next thing to do is send our public key and receive client's
    // this corresponds to server step 3 and step 4 in the diagram

    System.out.println("Sending my public key...");
    byte[] keyBytes = keyPair.getPublic().getEncoded();
    out.writeInt(keyBytes.length);
    out.write(keyBytes);
    System.out.println("Server public key bytes: " + CryptoUtils.toHex(keyBytes));

    // receive the client's public key

    System.out.println("Receiving client's public key...");
    DataInputStream in = new DataInputStream(socket.getInputStream());
    keyBytes = new byte[in.readInt()];
    in.readFully(keyBytes);

    // create client's public key

    KeyFactory kf = KeyFactory.getInstance("DH");
    X509EncodedKeySpec x509Spec = new X509EncodedKeySpec(keyBytes);
    PublicKey clientPublicKey = kf.generatePublic(x509Spec);

    // print out client's public key bytes

    System.out.println(
        "Client public key bytes: " + CryptoUtils.toHex(clientPublicKey.getEncoded()));

    // we can now use the client's public key and
    // our own private key to perform the key agreement

    System.out.println("Performing the key agreement ... ");
    KeyAgreement ka = KeyAgreement.getInstance("DH");
    ka.init(keyPair.getPrivate());
    ka.doPhase(clientPublicKey, true);

    // in a chat application, each character is sendt over the wire, separetly encrypted,
    // Instead of using ECB, we are goin to use CFB, with a block size of 8 bits(1byte)
    // to send each character. We will encrypt the same character in a different way
    // each time. But in order to use CFB8, we need an IVof 8 bytes. We will create
    // that IV randomly and and send it to the client. It doesn't matter if somoene
    // eavesdrops on the IV when it is sent over the wire. it's not sensitive info

    // creating the IV and sending it corresponds to step 6 and 7

    byte[] iv = new byte[8];
    SecureRandom sr = new SecureRandom();
    sr.nextBytes(iv);
    out.write(iv);

    // we generate the secret byte array we share with the client and use it
    // to create the session key (Step 8)

    byte[] sessionKeyBytes = ka.generateSecret();

    // create the session key

    SecretKeyFactory skf = SecretKeyFactory.getInstance("DESede");
    DESedeKeySpec DESedeSpec = new DESedeKeySpec(sessionKeyBytes);
    SecretKey sessionKey = skf.generateSecret(DESedeSpec);

    // printout session key bytes

    System.out.println("Session key bytes: " + CryptoUtils.toHex(sessionKey.getEncoded()));

    // now use tha that session key and IV to create a CipherInputStream. We will use them to read
    // all character
    // that are sent to us by the client

    System.out.println("Creating the cipher stream ...");
    Cipher decrypter = Cipher.getInstance("DESede/CFB8/NoPadding");
    IvParameterSpec spec = new IvParameterSpec(iv);
    decrypter.init(Cipher.DECRYPT_MODE, sessionKey, spec);
    CipherInputStream cipherIn = new CipherInputStream(socket.getInputStream(), decrypter);

    // we just keep reading the input and print int to the screen, until -1 sent over

    int theCharacter = 0;
    theCharacter = cipherIn.read();
    while (theCharacter != -1) {
      System.out.print((char) theCharacter);
      theCharacter = cipherIn.read();
    }
    // once -1 is received we want to close up our stream and exit

    cipherIn.close();
    in.close();
    out.close();
    socket.close();
  }
예제 #5
-1
  /*
   * Calculate the keys needed for this connection, once the session's
   * master secret has been calculated.  Uses the master key and nonces;
   * the amount of keying material generated is a function of the cipher
   * suite that's been negotiated.
   *
   * This gets called both on the "full handshake" (where we exchanged
   * a premaster secret and started a new session) as well as on the
   * "fast handshake" (where we just resumed a pre-existing session).
   */
  void calculateConnectionKeys(SecretKey masterKey) {
    /*
     * For both the read and write sides of the protocol, we use the
     * master to generate MAC secrets and cipher keying material.  Block
     * ciphers need initialization vectors, which we also generate.
     *
     * First we figure out how much keying material is needed.
     */
    int hashSize = cipherSuite.macAlg.size;
    boolean is_exportable = cipherSuite.exportable;
    BulkCipher cipher = cipherSuite.cipher;
    int expandedKeySize = is_exportable ? cipher.expandedKeySize : 0;

    // Which algs/params do we need to use?
    String keyMaterialAlg;
    PRF prf;

    if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
      keyMaterialAlg = "SunTls12KeyMaterial";
      prf = cipherSuite.prfAlg;
    } else {
      keyMaterialAlg = "SunTlsKeyMaterial";
      prf = P_NONE;
    }

    String prfHashAlg = prf.getPRFHashAlg();
    int prfHashLength = prf.getPRFHashLength();
    int prfBlockSize = prf.getPRFBlockSize();

    TlsKeyMaterialParameterSpec spec =
        new TlsKeyMaterialParameterSpec(
            masterKey,
            protocolVersion.major,
            protocolVersion.minor,
            clnt_random.random_bytes,
            svr_random.random_bytes,
            cipher.algorithm,
            cipher.keySize,
            expandedKeySize,
            cipher.ivSize,
            hashSize,
            prfHashAlg,
            prfHashLength,
            prfBlockSize);

    try {
      KeyGenerator kg = JsseJce.getKeyGenerator(keyMaterialAlg);
      kg.init(spec);
      TlsKeyMaterialSpec keySpec = (TlsKeyMaterialSpec) kg.generateKey();

      clntWriteKey = keySpec.getClientCipherKey();
      svrWriteKey = keySpec.getServerCipherKey();

      // Return null if IVs are not supposed to be generated.
      // e.g. TLS 1.1+.
      clntWriteIV = keySpec.getClientIv();
      svrWriteIV = keySpec.getServerIv();

      clntMacSecret = keySpec.getClientMacKey();
      svrMacSecret = keySpec.getServerMacKey();
    } catch (GeneralSecurityException e) {
      throw new ProviderException(e);
    }

    //
    // Dump the connection keys as they're generated.
    //
    if (debug != null && Debug.isOn("keygen")) {
      synchronized (System.out) {
        HexDumpEncoder dump = new HexDumpEncoder();

        System.out.println("CONNECTION KEYGEN:");

        // Inputs:
        System.out.println("Client Nonce:");
        printHex(dump, clnt_random.random_bytes);
        System.out.println("Server Nonce:");
        printHex(dump, svr_random.random_bytes);
        System.out.println("Master Secret:");
        printHex(dump, masterKey.getEncoded());

        // Outputs:
        System.out.println("Client MAC write Secret:");
        printHex(dump, clntMacSecret.getEncoded());
        System.out.println("Server MAC write Secret:");
        printHex(dump, svrMacSecret.getEncoded());

        if (clntWriteKey != null) {
          System.out.println("Client write key:");
          printHex(dump, clntWriteKey.getEncoded());
          System.out.println("Server write key:");
          printHex(dump, svrWriteKey.getEncoded());
        } else {
          System.out.println("... no encryption keys used");
        }

        if (clntWriteIV != null) {
          System.out.println("Client write IV:");
          printHex(dump, clntWriteIV.getIV());
          System.out.println("Server write IV:");
          printHex(dump, svrWriteIV.getIV());
        } else {
          if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
            System.out.println("... no IV derived for this protocol");
          } else {
            System.out.println("... no IV used for this cipher");
          }
        }
        System.out.flush();
      }
    }
  }
예제 #6
-5
  /*
   * Calculate the master secret from its various components.  This is
   * used for key exchange by all cipher suites.
   *
   * The master secret is the catenation of three MD5 hashes, each
   * consisting of the pre-master secret and a SHA1 hash.  Those three
   * SHA1 hashes are of (different) constant strings, the pre-master
   * secret, and the nonces provided by the client and the server.
   */
  private SecretKey calculateMasterSecret(
      SecretKey preMasterSecret, ProtocolVersion requestedVersion) {

    if (debug != null && Debug.isOn("keygen")) {
      HexDumpEncoder dump = new HexDumpEncoder();

      System.out.println("SESSION KEYGEN:");

      System.out.println("PreMaster Secret:");
      printHex(dump, preMasterSecret.getEncoded());

      // Nonces are dumped with connection keygen, no
      // benefit to doing it twice
    }

    // What algs/params do we need to use?
    String masterAlg;
    PRF prf;

    if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
      masterAlg = "SunTls12MasterSecret";
      prf = cipherSuite.prfAlg;
    } else {
      masterAlg = "SunTlsMasterSecret";
      prf = P_NONE;
    }

    String prfHashAlg = prf.getPRFHashAlg();
    int prfHashLength = prf.getPRFHashLength();
    int prfBlockSize = prf.getPRFBlockSize();

    TlsMasterSecretParameterSpec spec =
        new TlsMasterSecretParameterSpec(
            preMasterSecret,
            protocolVersion.major,
            protocolVersion.minor,
            clnt_random.random_bytes,
            svr_random.random_bytes,
            prfHashAlg,
            prfHashLength,
            prfBlockSize);

    SecretKey masterSecret;
    try {
      KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg);
      kg.init(spec);
      masterSecret = kg.generateKey();
    } catch (GeneralSecurityException e) {
      // For RSA premaster secrets, do not signal a protocol error
      // due to the Bleichenbacher attack. See comments further down.
      if (!preMasterSecret.getAlgorithm().equals("TlsRsaPremasterSecret")) {
        throw new ProviderException(e);
      }

      if (debug != null && Debug.isOn("handshake")) {
        System.out.println("RSA master secret generation error:");
        e.printStackTrace(System.out);
        System.out.println("Generating new random premaster secret");
      }

      if (requestedVersion != null) {
        preMasterSecret = RSAClientKeyExchange.generateDummySecret(requestedVersion);
      } else {
        preMasterSecret = RSAClientKeyExchange.generateDummySecret(protocolVersion);
      }

      // recursive call with new premaster secret
      return calculateMasterSecret(preMasterSecret, null);
    }

    // if no version check requested (client side handshake), or version
    // information is not available (not an RSA premaster secret),
    // return master secret immediately.
    if ((requestedVersion == null) || !(masterSecret instanceof TlsMasterSecret)) {
      return masterSecret;
    }

    // we have checked the ClientKeyExchange message when reading TLS
    // record, the following check is necessary to ensure that
    // JCE provider does not ignore the checking, or the previous
    // checking process bypassed the premaster secret version checking.
    TlsMasterSecret tlsKey = (TlsMasterSecret) masterSecret;
    int major = tlsKey.getMajorVersion();
    int minor = tlsKey.getMinorVersion();
    if ((major < 0) || (minor < 0)) {
      return masterSecret;
    }

    // check if the premaster secret version is ok
    // the specification says that it must be the maximum version supported
    // by the client from its ClientHello message. However, many
    // implementations send the negotiated version, so accept both
    // for SSL v3.0 and TLS v1.0.
    // NOTE that we may be comparing two unsupported version numbers, which
    // is why we cannot use object reference equality in this special case.
    ProtocolVersion premasterVersion = ProtocolVersion.valueOf(major, minor);
    boolean versionMismatch = (premasterVersion.v != requestedVersion.v);

    /*
     * we never checked the client_version in server side
     * for TLS v1.0 and SSL v3.0. For compatibility, we
     * maintain this behavior.
     */
    if (versionMismatch && requestedVersion.v <= ProtocolVersion.TLS10.v) {
      versionMismatch = (premasterVersion.v != protocolVersion.v);
    }

    if (versionMismatch == false) {
      // check passed, return key
      return masterSecret;
    }

    // Due to the Bleichenbacher attack, do not signal a protocol error.
    // Generate a random premaster secret and continue with the handshake,
    // which will fail when verifying the finished messages.
    // For more information, see comments in PreMasterSecret.
    if (debug != null && Debug.isOn("handshake")) {
      System.out.println(
          "RSA PreMasterSecret version error: expected"
              + protocolVersion
              + " or "
              + requestedVersion
              + ", decrypted: "
              + premasterVersion);
      System.out.println("Generating new random premaster secret");
    }
    preMasterSecret = RSAClientKeyExchange.generateDummySecret(requestedVersion);

    // recursive call with new premaster secret
    return calculateMasterSecret(preMasterSecret, null);
  }