예제 #1
0
  public void writeSession(HttpServletRequest request, HttpServletResponse response)
      throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException,
          BadPaddingException, IllegalBlockSizeException {
    SparkHttpRequestWrapper sparkRequest = (SparkHttpRequestWrapper) request;
    if (!sparkRequest.sessionAccessed()) return;
    CookieSession session = (CookieSession) request.getSession();

    // serialize session
    byte[] sessionBytes = conf.asByteArray(session);

    // encrypt content
    final Cipher symmetricalCipher = Cipher.getInstance(symmetricEncryptionAlgorithm);
    symmetricalCipher.init(Cipher.ENCRYPT_MODE, this.symmetricEncryptionKey);
    byte[] encryptedBytes = symmetricalCipher.doFinal(sessionBytes);

    // sign content
    byte[] signature = sign(encryptedBytes);
    byte[] cookieContent = new byte[encryptedBytes.length + signature.length];

    System.arraycopy(encryptedBytes, 0, cookieContent, 0, encryptedBytes.length);
    System.arraycopy(
        signature, 0, cookieContent, cookieContent.length - signature.length, signature.length);

    String base64CookieContent = Base64.getEncoder().encodeToString(cookieContent);
    addCookie(base64CookieContent, response);
  }
예제 #2
0
 private static void concat(byte[] src, byte[] dst, int start, int len) {
   if (src.length == 0) {
     return;
   }
   int loop = len / src.length;
   int off, i;
   for (i = 0, off = 0; i < loop; i++, off += src.length)
     System.arraycopy(src, 0, dst, off + start, src.length);
   System.arraycopy(src, 0, dst, off + start, len - off);
 }
예제 #3
0
 void getTable() {
   if (chooser == null) {
     File userdir = new File(System.getProperty("user.dir"));
     chooser = new JFileChooser(userdir);
   }
   if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
     file = chooser.getSelectedFile();
     fileLength = file.length();
     setTitle(windowTitle + ": " + file.getAbsolutePath());
     int size = Key.getEncryptionKeySize(this, true);
     key = Key.getEncryptionKey(this, true, size);
     if (key == null) key = defaultKey;
     initCipher();
   } else System.exit(0);
 }
 public static void main(String[] args) throws Exception {
   //
   // check args and get plaintext
   if (args.length != 1) {
     System.err.println("Usage: java MessageAuthenticationCodeExample text");
     System.exit(1);
   }
   byte[] plainText = args[0].getBytes("UTF8");
   //
   // get a key for the HmacMD5 algorithm
   System.out.println("\nStart generating key");
   KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
   SecretKey MD5key = keyGen.generateKey();
   System.out.println("Finish generating key");
   //
   // get a MAC object and update it with the plaintext
   Mac mac = Mac.getInstance("HmacMD5");
   mac.init(MD5key);
   mac.update(plainText);
   //
   // print out the provider used and the MAC
   System.out.println("\n" + mac.getProvider().getInfo());
   System.out.println("\nMAC: ");
   System.out.println(new String(mac.doFinal(), "UTF8"));
 }
예제 #5
0
 /**
  * The ActionListener implementation
  *
  * @param event the event.
  */
 public void actionPerformed(ActionEvent event) {
   String searchText = textField.getText().trim();
   if (searchText.equals("") && !saveAs.isSelected() && (fileLength > 10000000)) {
     textPane.setText("Blank search text is not allowed for large IdTables.");
   } else {
     File outputFile = null;
     if (saveAs.isSelected()) {
       outputFile = chooser.getSelectedFile();
       if (outputFile != null) {
         String name = outputFile.getName();
         int k = name.lastIndexOf(".");
         if (k != -1) name = name.substring(0, k);
         name += ".txt";
         File parent = outputFile.getAbsoluteFile().getParentFile();
         outputFile = new File(parent, name);
         chooser.setSelectedFile(outputFile);
       }
       if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) System.exit(0);
       outputFile = chooser.getSelectedFile();
     }
     textPane.setText("");
     Searcher searcher = new Searcher(searchText, event.getSource().equals(searchPHI), outputFile);
     searcher.start();
   }
 }
  public void run() {
    try {
      input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
      output = new PrintWriter(clientSocket.getOutputStream(), true);
      InputStream in = clientSocket.getInputStream();
      objIn = new ObjectInputStream(in);
      String outputLine;
      String inputLine;
      long time = System.currentTimeMillis();

      // Inicia la comunicación con el cliente
      ProtocoloClinica kkp = new ProtocoloClinica(bean);
      outputLine = kkp.processMessage(null);
      output.println(outputLine);

      // Continua la comunicación con el cliente
      while ((inputLine = input.readLine()) != null) {
        outputLine = kkp.processMessage(inputLine);
        if (outputLine.equals("RECIBIDA")) {
          leer();
        } else {
          output.println(outputLine);
        }
        if (outputLine.equals("OVER")) break;
      }
      killFrijolito();
      System.out.println("Request processed: " + time);
    } catch (IOException e) {
      // report exception somewhere.
      e.printStackTrace();
    }
  }
예제 #7
0
 public void init(int mode, byte[] key, byte[] iv) throws Exception {
   byte[] tmp;
   if (key.length > bsize) {
     tmp = new byte[bsize];
     System.arraycopy(key, 0, tmp, 0, tmp.length);
     key = tmp;
   }
   try {
     cipher = javax.crypto.Cipher.getInstance("RC4");
     SecretKeySpec _key = new SecretKeySpec(key, "RC4");
     synchronized (javax.crypto.Cipher.class) {
       cipher.init(
           (mode == ENCRYPT_MODE
               ? javax.crypto.Cipher.ENCRYPT_MODE
               : javax.crypto.Cipher.DECRYPT_MODE),
           _key);
     }
     byte[] foo = new byte[1];
     for (int i = 0; i < skip; i++) {
       cipher.update(foo, 0, 1, foo, 0);
     }
   } catch (Exception e) {
     cipher = null;
     throw e;
   }
 }
예제 #8
0
  private static void permissionCheck() {
    SecurityManager sec = System.getSecurityManager();

    if (sec != null) {
      sec.checkPermission(new RuntimePermission("useKeychainStore"));
    }
  }
예제 #9
0
파일: TestGCM.java 프로젝트: kexianda/misc
  private static int runEncryptCase(
      String k_hex,
      String p_hex,
      String iv_hex,
      String aad_hex,
      String c_hex,
      String t_hex,
      String hint) {
    byte[] K = hexStrToBytes(k_hex);
    byte[] P = hexStrToBytes(p_hex);
    byte[] IV = hexStrToBytes(iv_hex);
    byte[] AAD = hexStrToBytes(aad_hex);

    byte[] C = hexStrToBytes(c_hex);
    byte[] T = hexStrToBytes(t_hex);

    byte[] output = gcmEncrypt(K, P, AAD, IV);

    byte[] cipher = new byte[output.length - BLOCK_SIZE];
    byte[] tag = new byte[BLOCK_SIZE];
    System.arraycopy(output, 0, cipher, 0, output.length - BLOCK_SIZE);
    System.arraycopy(output, output.length - BLOCK_SIZE, tag, 0, BLOCK_SIZE);

    System.out.println("-------------------------------------");
    int errNo = 0;
    errNo = compareArrays(cipher, C);
    if (errNo > 0) {
      System.out.println(hint + " data encryption failed!");
    } else {
      System.out.println(hint + " data encryption passed!");
    }

    if (compareArrays(tag, T) > 0) {
      errNo++;
      System.out.println(hint + " tag verification failed!");
    } else {
      System.out.println(hint + " tag verification passed!");
    }

    return errNo;
  }
 private static byte[] expandToOneBlock(byte[] in, int inOfs, int len) {
   if (len > AES_BLOCK_SIZE) {
     throw new ProviderException("input " + len + " too long");
   }
   if (len == AES_BLOCK_SIZE && inOfs == 0) {
     return in;
   } else {
     byte[] paddedIn = new byte[AES_BLOCK_SIZE];
     System.arraycopy(in, inOfs, paddedIn, 0, len);
     return paddedIn;
   }
 }
예제 #11
0
  public static void main(String[] args) throws Exception {
    //
    // verifica args e recebe o texto plano
    if (args.length != 1) {
      System.err.println("Usage: java DigitalSignatureExample text");
      System.exit(1);
    }
    byte[] plainText = args[0].getBytes("UTF8");
    //
    // gera o par de chaves RSA
    System.out.println("\nStart generating RSA key");
    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
    keyGen.initialize(1024);
    KeyPair key = keyGen.generateKeyPair();
    System.out.println("Finish generating RSA key");
    //
    // define um objeto signature para utilizar MD5 e RSA
    // e assina o texto plano com a chave privada,
    // o provider utilizado tambem eh impresso
    Signature sig = Signature.getInstance("MD5WithRSA");
    sig.initSign(key.getPrivate());
    sig.update(plainText);
    byte[] signature = sig.sign();
    System.out.println(sig.getProvider().getInfo());
    System.out.println("\nSignature:");

    // converte o signature para hexadecimal
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < signature.length; i++) {
      String hex = Integer.toHexString(0x0100 + (signature[i] & 0x00FF)).substring(1);
      buf.append((hex.length() < 2 ? "0" : "") + hex);
    }

    // imprime o signature em hexadecimal
    System.out.println(buf.toString());

    //
    // verifica a assinatura com a chave publica
    System.out.println("\nStart signature verification");
    sig.initVerify(key.getPublic());
    sig.update(plainText);
    try {
      if (sig.verify(signature)) {
        System.out.println("Signature verified");
      } else System.out.println("Signature failed");
    } catch (SignatureException se) {
      System.out.println("Singature failed");
    }
  }
예제 #12
0
  // Reads the contents of the passed file into a string
  public String getContents(File file) {
    StringBuilder result = new StringBuilder();

    try {
      BufferedReader input = new BufferedReader(new FileReader(file));
      String nextLine = new String();

      while ((nextLine = input.readLine()) != null) {
        result.append(nextLine);
        result.append(System.getProperty("line.separator"));
      }

      input.close();
    } catch (Exception e) {
      System.out.println("Encryption/Decryption File Error: " + e);
    }

    return result.toString();
  }
  /**
   * Performs decryption operation for the last time.
   *
   * <p>NOTE: For cipher feedback modes which does not perform special handling for the last few
   * blocks, this is essentially the same as <code>encrypt(...)</code>. Given most modes do not do
   * special handling, the default impl for this method is to simply call <code>decrypt(...)</code>.
   *
   * @param in the input buffer with the data to be decrypted
   * @param inOfs the offset in <code>cipher</code>
   * @param len the length of the input data
   * @param out the buffer for the decryption result
   * @param outOfs the offset in <code>plain</code>
   * @return the number of bytes placed into the <code>out</code> buffer
   */
  int decryptFinal(byte[] in, int inOfs, int len, byte[] out, int outOfs)
      throws IllegalBlockSizeException, AEADBadTagException, ShortBufferException {
    if (len < tagLenBytes) {
      throw new AEADBadTagException("Input too short - need tag");
    }
    if (out.length - outOfs < ((ibuffer.size() + len) - tagLenBytes)) {
      throw new ShortBufferException("Output buffer too small");
    }
    processAAD();
    if (len != 0) {
      ibuffer.write(in, inOfs, len);
    }

    // refresh 'in' to all buffered-up bytes
    in = ibuffer.toByteArray();
    inOfs = 0;
    len = in.length;
    ibuffer.reset();

    byte[] tag = new byte[tagLenBytes];
    // get the trailing tag bytes from 'in'
    System.arraycopy(in, len - tagLenBytes, tag, 0, tagLenBytes);
    len -= tagLenBytes;

    if (len > 0) {
      doLastBlock(in, inOfs, len, out, outOfs, false);
    }

    byte[] lengthBlock = getLengthBlock(sizeOfAAD * 8, processed * 8);
    ghashAllToS.update(lengthBlock);

    byte[] s = ghashAllToS.digest();
    byte[] sOut = new byte[s.length];
    GCTR gctrForSToTag = new GCTR(embeddedCipher, this.preCounterBlock);
    gctrForSToTag.doFinal(s, 0, s.length, sOut, 0);
    for (int i = 0; i < tagLenBytes; i++) {
      if (tag[i] != sOut[i]) {
        throw new AEADBadTagException("Tag mismatch!");
      }
    }
    return len;
  }
예제 #14
0
  public String toString() {
    String LINE_SEP = System.getProperty("line.separator");

    StringBuffer strbuf =
        new StringBuffer(
            "SunJCE Diffie-Hellman Public Key:"
                + LINE_SEP
                + "y:"
                + LINE_SEP
                + Debug.toHexString(this.y)
                + LINE_SEP
                + "p:"
                + LINE_SEP
                + Debug.toHexString(this.p)
                + LINE_SEP
                + "g:"
                + LINE_SEP
                + Debug.toHexString(this.g));
    if (this.l != 0) strbuf.append(LINE_SEP + "l:" + LINE_SEP + "    " + this.l);
    return strbuf.toString();
  }
  /**
   * Performs encryption operation for the last time.
   *
   * @param in the input buffer with the data to be encrypted
   * @param inOfs the offset in <code>in</code>
   * @param len the length of the input data
   * @param out the buffer for the encryption result
   * @param outOfs the offset in <code>out</code>
   * @return the number of bytes placed into the <code>out</code> buffer
   */
  int encryptFinal(byte[] in, int inOfs, int len, byte[] out, int outOfs)
      throws IllegalBlockSizeException, ShortBufferException {
    if (out.length - outOfs < (len + tagLenBytes)) {
      throw new ShortBufferException("Output buffer too small");
    }

    processAAD();
    if (len > 0) {
      doLastBlock(in, inOfs, len, out, outOfs, true);
    }

    byte[] lengthBlock = getLengthBlock(sizeOfAAD * 8, processed * 8);
    ghashAllToS.update(lengthBlock);
    byte[] s = ghashAllToS.digest();
    byte[] sOut = new byte[s.length];
    GCTR gctrForSToTag = new GCTR(embeddedCipher, this.preCounterBlock);
    gctrForSToTag.doFinal(s, 0, s.length, sOut, 0);

    System.arraycopy(sOut, 0, out, (outOfs + len), tagLenBytes);
    return (len + tagLenBytes);
  }
예제 #16
0
 private int implDoFinal(byte[] out, int outOfs, int outLen)
     throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
   int requiredOutLen = doFinalLength(0);
   if (outLen < requiredOutLen) {
     throw new ShortBufferException();
   }
   try {
     ensureInitialized();
     int k = 0;
     if (encrypt) {
       if (paddingObj != null) {
         int actualPadLen = paddingObj.setPaddingBytes(padBuffer, requiredOutLen - bytesBuffered);
         k =
             token.p11.C_EncryptUpdate(
                 session.id(), 0, padBuffer, 0, actualPadLen, 0, out, outOfs, outLen);
       }
       k += token.p11.C_EncryptFinal(session.id(), 0, out, (outOfs + k), (outLen - k));
     } else {
       if (paddingObj != null) {
         if (padBufferLen != 0) {
           k =
               token.p11.C_DecryptUpdate(
                   session.id(), 0, padBuffer, 0, padBufferLen, 0, padBuffer, 0, padBuffer.length);
         }
         k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k, padBuffer.length - k);
         int actualPadLen = paddingObj.unpad(padBuffer, k);
         k -= actualPadLen;
         System.arraycopy(padBuffer, 0, out, outOfs, k);
       } else {
         k = token.p11.C_DecryptFinal(session.id(), 0, out, outOfs, outLen);
       }
     }
     return k;
   } catch (PKCS11Exception e) {
     handleException(e);
     throw new ProviderException("doFinal() failed", e);
   } finally {
     reset();
   }
 }
예제 #17
0
  public void init(int mode, byte[] key, byte[] iv) throws Exception {
    String pad = "NoPadding";
    byte[] tmp;
    if (key.length > bsize) {
      tmp = new byte[bsize];
      System.arraycopy(key, 0, tmp, 0, tmp.length);
      key = tmp;
    }

    try {
      cipher = javax.crypto.Cipher.getInstance("RC4");
      SecretKeySpec _key = new SecretKeySpec(key, "RC4");
      cipher.init(
          (mode == ENCRYPT_MODE
              ? javax.crypto.Cipher.ENCRYPT_MODE
              : javax.crypto.Cipher.DECRYPT_MODE),
          _key);
    } catch (Exception e) {
      cipher = null;
      throw e;
    }
  }
예제 #18
0
  // Uses supplied hash algorithm
  static byte[] derive(
      char[] chars, byte[] salt, int ic, int n, int type, String hashAlgo, int blockLength) {

    // Add in trailing NULL terminator.  Special case:
    // no terminator if password is "\0".
    int length = chars.length * 2;
    if (length == 2 && chars[0] == 0) {
      chars = new char[0];
      length = 0;
    } else {
      length += 2;
    }

    byte[] passwd = new byte[length];
    for (int i = 0, j = 0; i < chars.length; i++, j += 2) {
      passwd[j] = (byte) ((chars[i] >>> 8) & 0xFF);
      passwd[j + 1] = (byte) (chars[i] & 0xFF);
    }
    byte[] key = new byte[n];

    try {
      MessageDigest sha = MessageDigest.getInstance(hashAlgo);

      int v = blockLength;
      int u = sha.getDigestLength();
      int c = roundup(n, u) / u;
      byte[] D = new byte[v];
      int s = roundup(salt.length, v);
      int p = roundup(passwd.length, v);
      byte[] I = new byte[s + p];

      Arrays.fill(D, (byte) type);
      concat(salt, I, 0, s);
      concat(passwd, I, s, p);

      byte[] Ai;
      byte[] B = new byte[v];
      byte[] tmp = new byte[v];

      int i = 0;
      for (; ; i++, n -= u) {
        sha.update(D);
        sha.update(I);
        Ai = sha.digest();
        for (int r = 1; r < ic; r++) Ai = sha.digest(Ai);
        System.arraycopy(Ai, 0, key, u * i, Math.min(n, u));
        if (i + 1 == c) break;
        concat(Ai, B, 0, B.length);
        BigInteger B1;
        B1 = new BigInteger(1, B).add(BigInteger.ONE);

        for (int j = 0; j < I.length; j += v) {
          BigInteger Ij;
          int trunc;

          if (tmp.length != v) tmp = new byte[v];
          System.arraycopy(I, j, tmp, 0, v);
          Ij = new BigInteger(1, tmp);
          Ij = Ij.add(B1);
          tmp = Ij.toByteArray();
          trunc = tmp.length - v;
          if (trunc >= 0) {
            System.arraycopy(tmp, trunc, I, j, v);
          } else if (trunc < 0) {
            Arrays.fill(I, j, j + (-trunc), (byte) 0);
            System.arraycopy(tmp, 0, I, j + (-trunc), tmp.length);
          }
        }
      }
    } catch (Exception e) {
      throw new RuntimeException("internal error: " + e);
    }
    return key;
  }
  // Program demonstrating how to create a random key and then search for the key value.
  public static void main(String[] args) {
    if (2 != args.length) {
      System.out.println("Usage: java SealedDES #KEYSIZE #NUMTHREADS");
      return;
    }

    // create object to printf to the console
    PrintStream p = new PrintStream(System.out);

    // Get the argument
    long keybits = Long.parseLong(args[0]);
    int numThreads = Integer.parseInt(args[1]);

    long maxkey = ~(0L);
    maxkey = maxkey >>> (64 - keybits);

    // Create a simple cipher
    SealedDES enccipher = new SealedDES();

    // Get a number between 0 and 2^64 - 1
    Random generator = new Random();
    long key = generator.nextLong();

    // Mask off the high bits so we get a short key
    key = key & maxkey;

    // Set up a key
    enccipher.setKey(key);

    // Generate a sample string
    String plainstr = "Johns Hopkins afraid of the big bad wolf?";

    long runstart;
    runstart = System.currentTimeMillis();
    Thread[] threads = new Thread[numThreads];
    Runnable[] decrypters = new Runnable[numThreads];

    long keySpaceSize = 0;
    if (numThreads > 0) {
      keySpaceSize = maxkey / numThreads;
    }

    for (int i = 0; i < numThreads; i++) {
      SealedObject sldObj = enccipher.encrypt(plainstr);
      decrypters[i] =
          new DecryptionRunner(
              i, new SealedDES(), keySpaceSize * i, keySpaceSize * (i + 1), sldObj);
      threads[i] = new Thread(decrypters[i]);
      threads[i].start();
    }

    for (int i = 0; i < numThreads; i++) {
      try {
        threads[i].join();
      } catch (InterruptedException e) {
        System.out.println("Join on thread [" + i + "] interrupted");
        break;
      }
    }

    // Output search time
    long elapsed = System.currentTimeMillis() - runstart;
    long keys = maxkey + 1;
    System.out.println("Completed search of " + keys + " keys at " + elapsed + " milliseconds.");
  }
예제 #20
0
  public ArrayList handleEncryptedKey(
      Element xencEncryptedKey, CallbackHandler cb, Crypto crypto, PrivateKey privateKey)
      throws WSSecurityException {
    long t0 = 0, t1 = 0, t2 = 0;
    if (tlog.isDebugEnabled()) {
      t0 = System.currentTimeMillis();
    }
    // need to have it to find the encrypted data elements in the envelope
    Document doc = xencEncryptedKey.getOwnerDocument();

    // lookup xenc:EncryptionMethod, get the Algorithm attribute to determine
    // how the key was encrypted. Then check if we support the algorithm

    Node tmpE = null; // short living Element used for lookups only
    tmpE =
        (Element)
            WSSecurityUtil.getDirectChild(
                (Node) xencEncryptedKey, "EncryptionMethod", WSConstants.ENC_NS);
    if (tmpE != null) {
      this.encryptedKeyTransportMethod = ((Element) tmpE).getAttribute("Algorithm");
    }
    if (this.encryptedKeyTransportMethod == null) {
      throw new WSSecurityException(WSSecurityException.UNSUPPORTED_ALGORITHM, "noEncAlgo");
    }
    Cipher cipher = WSSecurityUtil.getCipherInstance(this.encryptedKeyTransportMethod);
    //
    // Well, we can decrypt the session (symmetric) key. Now lookup CipherValue, this is the
    // value of the encrypted session key (session key usually is a symmetrical key that encrypts
    // the referenced content). This is a 2-step lookup
    //
    Element xencCipherValue = null;
    tmpE =
        (Element)
            WSSecurityUtil.getDirectChild(
                (Node) xencEncryptedKey, "CipherData", WSConstants.ENC_NS);
    if (tmpE != null) {
      xencCipherValue =
          (Element) WSSecurityUtil.getDirectChild(tmpE, "CipherValue", WSConstants.ENC_NS);
    }
    if (xencCipherValue == null) {
      throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "noCipher");
    }

    if (privateKey == null) {
      Element keyInfo =
          (Element)
              WSSecurityUtil.getDirectChild((Node) xencEncryptedKey, "KeyInfo", WSConstants.SIG_NS);
      String alias;
      if (keyInfo != null) {
        Element secRefToken =
            (Element)
                WSSecurityUtil.getDirectChild(
                    keyInfo, "SecurityTokenReference", WSConstants.WSSE_NS);
        //
        // EncryptedKey must a a STR as child of KeyInfo, KeyName
        // valid only for EncryptedData
        //
        //  if (secRefToken == null) {
        //      secRefToken = (Element) WSSecurityUtil.getDirectChild(keyInfo,
        //              "KeyName", WSConstants.SIG_NS);
        //  }
        if (secRefToken == null) {
          throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "noSecTokRef");
        }
        SecurityTokenReference secRef = new SecurityTokenReference(secRefToken);
        //
        // Well, at this point there are several ways to get the key.
        // Try to handle all of them :-).
        //
        alias = null;
        //
        // handle X509IssuerSerial here. First check if all elements are available,
        // get the appropriate data, check if all data is available.
        // If all is ok up to that point, look up the certificate alias according
        // to issuer name and serial number.
        // This method is recommended by OASIS WS-S specification, X509 profile
        //
        if (secRef.containsX509Data() || secRef.containsX509IssuerSerial()) {
          alias = secRef.getX509IssuerSerialAlias(crypto);
          if (log.isDebugEnabled()) {
            log.debug("X509IssuerSerial alias: " + alias);
          }
        }
        //
        // If wsse:KeyIdentifier found, then the public key of the attached cert was used to
        // encrypt the session (symmetric) key that encrypts the data. Extract the certificate
        // using the BinarySecurity token (was enhanced to handle KeyIdentifier too).
        // This method is _not_ recommended by OASIS WS-S specification, X509 profile
        //
        else if (secRef.containsKeyIdentifier()) {
          X509Certificate[] certs = null;
          if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType())) {
            Element token = secRef.getKeyIdentifierTokenElement(doc, docInfo, cb);

            if (crypto == null) {
              throw new WSSecurityException(WSSecurityException.FAILURE, "noSigCryptoFile");
            }
            SAMLKeyInfo samlKi = SAMLUtil.getSAMLKeyInfo(token, crypto, cb);
            certs = samlKi.getCerts();
          } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(
              secRef.getKeyIdentifierValueType())) {
            Element token = secRef.getKeyIdentifierTokenElement(doc, docInfo, cb);
            if (crypto == null) {
              throw new WSSecurityException(0, "noSigCryptoFile");
            }
            SAML2KeyInfo samlKi = SAML2Util.getSAML2KeyInfo(token, crypto, cb);
            certs = samlKi.getCerts();
          } else {
            certs = secRef.getKeyIdentifier(crypto);
          }
          if (certs == null || certs.length < 1 || certs[0] == null) {
            throw new WSSecurityException(
                WSSecurityException.FAILURE, "noCertsFound", new Object[] {"decryption (KeyId)"});
          }
          //
          // Here we have the certificate. Now find the alias for it. Needed to identify
          // the private key associated with this certificate
          //
          alias = crypto.getAliasForX509Cert(certs[0]);
          cert = certs[0];
          if (log.isDebugEnabled()) {
            log.debug("cert: " + certs[0]);
            log.debug("KeyIdentifier Alias: " + alias);
          }
        } else if (secRef.containsReference()) {
          Element bstElement = secRef.getTokenElement(doc, null, cb);

          // at this point ... check token type: Binary
          QName el = new QName(bstElement.getNamespaceURI(), bstElement.getLocalName());
          if (el.equals(WSSecurityEngine.binaryToken)) {
            X509Security token = new X509Security(bstElement);
            String value = bstElement.getAttribute(WSSecurityEngine.VALUE_TYPE);
            if (!X509Security.X509_V3_TYPE.equals(value) || (token == null)) {
              throw new WSSecurityException(
                  WSSecurityException.UNSUPPORTED_SECURITY_TOKEN,
                  "unsupportedBinaryTokenType",
                  new Object[] {"for decryption (BST)"});
            }
            cert = token.getX509Certificate(crypto);
            if (cert == null) {
              throw new WSSecurityException(
                  WSSecurityException.FAILURE, "noCertsFound", new Object[] {"decryption"});
            }
            //
            // Here we have the certificate. Now find the alias for it. Needed to identify
            // the private key associated with this certificate
            //
            alias = crypto.getAliasForX509Cert(cert);
            if (log.isDebugEnabled()) {
              log.debug("BST Alias: " + alias);
            }
          } else {
            throw new WSSecurityException(
                WSSecurityException.UNSUPPORTED_SECURITY_TOKEN, "unsupportedBinaryTokenType", null);
          }
          //
          // The following code is somewhat strange: the called crypto method gets
          // the keyname and searches for a certificate with an issuer's name that is
          // equal to this keyname. No serialnumber is used - IMHO this does
          // not identifies a certificate. In addition neither the WSS4J encryption
          // nor signature methods use this way to identify a certificate. Because of that
          // the next lines of code are disabled.
          //
          // } else if (secRef.containsKeyName()) {
          //    alias = crypto.getAliasForX509Cert(secRef.getKeyNameValue());
          //    if (log.isDebugEnabled()) {
          //        log.debug("KeyName alias: " + alias);
          //    }
        } else {
          throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "unsupportedKeyId");
        }
      } else if (crypto.getDefaultX509Alias() != null) {
        alias = crypto.getDefaultX509Alias();
      } else {
        throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "noKeyinfo");
      }
      //
      // At this point we have all information necessary to decrypt the session
      // key:
      // - the Cipher object intialized with the correct methods
      // - The data that holds the encrypted session key
      // - the alias name for the private key
      //
      // Now use the callback here to get password that enables
      // us to read the private key
      //
      WSPasswordCallback pwCb = new WSPasswordCallback(alias, WSPasswordCallback.DECRYPT);
      try {
        Callback[] callbacks = new Callback[] {pwCb};
        cb.handle(callbacks);
      } catch (IOException e) {
        throw new WSSecurityException(
            WSSecurityException.FAILURE, "noPassword", new Object[] {alias}, e);
      } catch (UnsupportedCallbackException e) {
        throw new WSSecurityException(
            WSSecurityException.FAILURE, "noPassword", new Object[] {alias}, e);
      }
      String password = pwCb.getPassword();
      if (password == null) {
        throw new WSSecurityException(
            WSSecurityException.FAILURE, "noPassword", new Object[] {alias});
      }

      try {
        privateKey = crypto.getPrivateKey(alias, password);
      } catch (Exception e) {
        throw new WSSecurityException(WSSecurityException.FAILED_CHECK, null, null, e);
      }
    }

    try {
      cipher.init(Cipher.DECRYPT_MODE, privateKey);
    } catch (Exception e1) {
      throw new WSSecurityException(WSSecurityException.FAILED_CHECK, null, null, e1);
    }

    try {
      encryptedEphemeralKey = getDecodedBase64EncodedData(xencCipherValue);
      decryptedBytes = cipher.doFinal(encryptedEphemeralKey);
    } catch (IllegalStateException e2) {
      throw new WSSecurityException(WSSecurityException.FAILED_CHECK, null, null, e2);
    } catch (Exception e2) {
      decryptedBytes =
          getRandomKey(
              getDataRefURIs(xencCipherValue), xencEncryptedKey.getOwnerDocument(), docInfo);
    }

    if (tlog.isDebugEnabled()) {
      t1 = System.currentTimeMillis();
    }

    // At this point we have the decrypted session (symmetric) key. According
    // to W3C XML-Enc this key is used to decrypt _any_ references contained in
    // the reference list
    // Now lookup the references that are encrypted with this key
    //
    Element refList =
        (Element)
            WSSecurityUtil.getDirectChild(
                (Node) xencEncryptedKey, "ReferenceList", WSConstants.ENC_NS);
    ArrayList dataRefs = new ArrayList();
    if (refList != null) {
      for (tmpE = refList.getFirstChild(); tmpE != null; tmpE = tmpE.getNextSibling()) {
        if (tmpE.getNodeType() != Node.ELEMENT_NODE) {
          continue;
        }
        if (!tmpE.getNamespaceURI().equals(WSConstants.ENC_NS)) {
          continue;
        }
        if (tmpE.getLocalName().equals("DataReference")) {
          String dataRefURI = ((Element) tmpE).getAttribute("URI");
          if (dataRefURI.charAt(0) == '#') {
            dataRefURI = dataRefURI.substring(1);
          }
          WSDataRef dataRef = decryptDataRef(doc, dataRefURI, decryptedBytes);
          dataRefs.add(dataRef);
        }
      }
      return dataRefs;
    }

    if (tlog.isDebugEnabled()) {
      t2 = System.currentTimeMillis();
      tlog.debug(
          "XMLDecrypt: total= "
              + (t2 - t0)
              + ", get-sym-key= "
              + (t1 - t0)
              + ", decrypt= "
              + (t2 - t1));
    }

    return null;
  }
예제 #21
0
 private final void bufferInputBytes(byte[] in, int inOfs, int len) {
   System.arraycopy(in, inOfs, padBuffer, padBufferLen, len);
   padBufferLen += len;
   bytesBuffered += len;
 }