com.quartzdesk.api.web.security.SecurityTokenUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of quartzdesk-api Show documentation
Show all versions of quartzdesk-api Show documentation
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.
/*
* 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 );
}
}
}