All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.quartzdesk.api.web.security.SecurityTokenUtils Maven / Gradle / Ivy

Go to download

QuartzDesk Public API library required for QuartzDesk Standard and Enterprise edition installations. This library must be placed on the classpath of the Quartz scheduler based application that is managed by QuartzDesk. It is important that this library is loaded by the same classloader that loads the Quartz scheduler API used by the application.

There is a newer version: 5.0.3
Show newest version
/*
 * Copyright (c) 2013-2019 QuartzDesk.com. All Rights Reserved.
 * QuartzDesk.com PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package com.quartzdesk.api.web.security;

import com.quartzdesk.api.ApiConst;
import com.quartzdesk.api.common.encoding.BASE64Decoder;
import com.quartzdesk.api.common.encoding.BASE64Encoder;
import com.quartzdesk.api.common.security.SecurityUtils;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Calendar;
import java.util.Random;

/**
 * Utility method for security token keys.
 *
 * @version $Id:$
 */
public final class SecurityTokenUtils
{
  private static final byte[] IV = new byte[] {
      0x76, (byte) 0xCE, (byte) 0xA3, 0x27,
      0x05, (byte) 0xD3, (byte) 0x9A, 0x63,
      0x25, 0x57, (byte) 0xB2, 0x71,
      0x03, 0x6F, (byte) 0x9C, 0x41 };

  private static final AlgorithmParameterSpec PARAM_SPEC = new IvParameterSpec( IV );

  private static final Random RANDOM = new SecureRandom();


  /**
   * Private constructor of a utility class.
   */
  private SecurityTokenUtils()
  {
  }


  /**
   * Decrypts the specified encrypted security token using the provided symmetric (AES) key.
   *
   * @param algorithm        a symmetric cipher algorithm.
   * @param key              a symmetric key.
   * @param securityTokenStr an encrypted security token.
   * @return the decrypted security token.
   * @throws SecurityException if an error occurs.
   */
  public static SecurityToken decrypt( SecurityTokenCipherAlgorithm algorithm, String key, String securityTokenStr )
  {
    try
    {
      SecretKey secretKey = SecurityUtils.symmetricKeyFromBASE64( key, algorithm.getKeyAlgorithm() );
      Cipher cipher = Cipher.getInstance( algorithm.getTransformation() );
      cipher.init( Cipher.DECRYPT_MODE, secretKey, PARAM_SPEC );

      String plainTextData =
          new String( cipher.doFinal( BASE64Decoder.decode( securityTokenStr ) ), ApiConst.ENCODING_UTF8 );

      String[] components = plainTextData.split( "\\|", -1 );
      if ( components.length != 3 )
        throw new SecurityException( "Invalid number of components in the security token: " + components.length );

      String validToStr = components[1];
      String principalName = components[2];
      if ( principalName.isEmpty() )
      {
        principalName = null;
      }

      Calendar validTo = Calendar.getInstance();
      validTo.setTimeInMillis( Long.parseLong( validToStr ) );

      Calendar now = Calendar.getInstance();
      if ( now.after( validTo ) )
        throw new SecurityException( "Security token expired on: " + validTo.getTime() );

      return new SecurityToken( principalName, validTo.getTime() );
    }
    catch ( SecurityException e )
    {
      throw e;
    }
    catch ( Exception e )
    {
      throw new SecurityException( e );
    }
  }


  /**
   * Encrypts the specified security token using the provided symmetric (AES) key.
   *
   * @param algorithm     a symmetric cipher algorithm, e.g. AES/CBC/PKCS5Padding.
   * @param key           a symmetric AES key.
   * @param securityToken a security token.
   * @return the encrypted security token as a BASE64 encoded string.
   * @throws SecurityException if an error occurs.
   */
  public static String encrypt( SecurityTokenCipherAlgorithm algorithm, String key, SecurityToken securityToken )
  {
    try
    {
      SecretKey secretKey = SecurityUtils.symmetricKeyFromBASE64( key, algorithm.getKeyAlgorithm() );
      Cipher cipher = Cipher.getInstance( algorithm.getTransformation() );
      cipher.init( Cipher.ENCRYPT_MODE, secretKey, PARAM_SPEC );

      StringBuilder plainTextData = new StringBuilder()

          // random string to prevent identical prefixes of security tokens generated in succession on the same date
          .append( Math.abs( RANDOM.nextInt( 65535 ) ) )

          .append( '|' )
          .append( securityToken.getValidTo().getTime() )

          .append( '|' )
          .append( securityToken.getPrincipalName() );

      byte[] result = cipher.doFinal( plainTextData.toString().getBytes( ApiConst.ENCODING_UTF8 ) );
      return BASE64Encoder.encode( result );
    }
    catch ( SecurityException e )
    {
      throw e;
    }
    catch ( Exception e )
    {
      throw new SecurityException( e );
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy