/**
   * Generates the signature over the query string.
   *
   * @param signingCredential credential that will be used to sign query string
   * @param algorithmURI algorithm URI of the signing credential
   * @param queryString query string to be signed
   * @return base64 encoded signature of query string
   * @throws MessageEncodingException there is an error computing the signature
   */
  protected String generateSignature(
      Credential signingCredential, String algorithmURI, String queryString)
      throws MessageEncodingException {

    log.debug(
        String.format(
            "Generating signature with key type '%s', algorithm URI '%s' over query string '%s'",
            CredentialSupport.extractSigningKey(signingCredential).getAlgorithm(),
            algorithmURI,
            queryString));

    String b64Signature = null;
    try {
      byte[] rawSignature =
          XMLSigningUtil.signWithURI(
              signingCredential, algorithmURI, queryString.getBytes("UTF-8"));
      b64Signature = Base64Support.encode(rawSignature, Base64Support.UNCHUNKED);
      log.debug("Generated digital signature value (base64-encoded) {}", b64Signature);
    } catch (final org.opensaml.security.SecurityException e) {
      throw new MessageEncodingException("Unable to sign URL query string", e);
    } catch (final UnsupportedEncodingException e) {
      // UTF-8 encoding is required to be supported by all JVMs
    }

    return b64Signature;
  }
  /**
   * Base64 the given SAML message.
   *
   * @param message the SAML message
   * @return Base64 encoded message
   * @throws MarshallingException if there is a problem marshalling the XMLObject
   * @throws UnsupportedEncodingException If the named charset is not supported
   */
  @Nonnull
  public String encodeMessage(@Nonnull final SAMLObject message)
      throws MarshallingException, UnsupportedEncodingException {
    final Element domMessage = XMLObjectSupport.marshall(message);
    final String messageXML = SerializeSupport.nodeToString(domMessage);

    return Base64Support.encode(messageXML.getBytes("UTF-8"), Base64Support.UNCHUNKED);
  }
  /**
   * DEFLATE (RFC1951) compresses the given SAML message.
   *
   * @param message SAML message
   * @return DEFLATE compressed message
   * @throws MessageEncodingException thrown if there is a problem compressing the message
   */
  protected String deflateAndBase64Encode(SAMLObject message) throws MessageEncodingException {
    log.debug("Deflating and Base64 encoding SAML message");
    try {
      String messageStr = SerializeSupport.nodeToString(marshallMessage(message));

      ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
      Deflater deflater = new Deflater(Deflater.DEFLATED, true);
      DeflaterOutputStream deflaterStream = new DeflaterOutputStream(bytesOut, deflater);
      deflaterStream.write(messageStr.getBytes("UTF-8"));
      deflaterStream.finish();

      return Base64Support.encode(bytesOut.toByteArray(), Base64Support.UNCHUNKED);
    } catch (IOException e) {
      throw new MessageEncodingException("Unable to DEFLATE and Base64 encode SAML message", e);
    }
  }