Ejemplo n.º 1
0
  public static void main(String[] args) {
    try {
      if (args[0].equals("-genkey")) {
        KeyPairGenerator pairgen = KeyPairGenerator.getInstance("RSA");
        SecureRandom random = new SecureRandom();
        pairgen.initialize(KEYSIZE, random);
        KeyPair keyPair = pairgen.generateKeyPair();
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(args[1]));
        out.writeObject(keyPair.getPublic());
        out.close();
        out = new ObjectOutputStream(new FileOutputStream(args[2]));
        out.writeObject(keyPair.getPrivate());
        out.close();
      } else if (args[0].equals("-encrypt")) {
        KeyGenerator keygen = KeyGenerator.getInstance("AES");
        SecureRandom random = new SecureRandom();
        keygen.init(random);
        SecretKey key = keygen.generateKey();

        // wrap with RSA public key
        ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(args[3]));
        Key publicKey = (Key) keyIn.readObject();
        keyIn.close();

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.WRAP_MODE, publicKey);
        byte[] wrappedKey = cipher.wrap(key);
        DataOutputStream out = new DataOutputStream(new FileOutputStream(args[2]));
        out.writeInt(wrappedKey.length);
        out.write(wrappedKey);

        InputStream in = new FileInputStream(args[1]);
        cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        crypt(in, out, cipher);
        in.close();
        out.close();
      } else {
        DataInputStream in = new DataInputStream(new FileInputStream(args[1]));
        int length = in.readInt();
        byte[] wrappedKey = new byte[length];
        in.read(wrappedKey, 0, length);

        // unwrap with RSA private key
        ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(args[3]));
        Key privateKey = (Key) keyIn.readObject();
        keyIn.close();

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.UNWRAP_MODE, privateKey);
        Key key = cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY);

        OutputStream out = new FileOutputStream(args[2]);
        cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, key);

        crypt(in, out, cipher);
        in.close();
        out.close();
      }
    } catch (IOException e) {
      e.printStackTrace();
    } catch (GeneralSecurityException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }
Ejemplo n.º 2
-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);
  }