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

edu.vt.middleware.crypt.AbstractEncryptionAlgorithm Maven / Gradle / Ivy

/**
 * As of "https://github.com/dfish3r/vt-crypt2 "CRYPT" (vt-crypt2) the source
 * code below the package "edu.vt.middleware.crypt" is dual licensed under both
 * the LGPL and Apache 2 license. As REFCODES.ORG source codes are also licensed
 * under the Apache License, v2.0 ("http://www.apache.org/licenses/TEXT-2.0"),
 * the according Apache 2 license principles are to be applied: "... The Apache
 * License is permissive; unlike copyleft licenses, it does not require a
 * derivative work of the software, or modifications to the original, to be
 * distributed using the same license. It still requires application of the same
 * license to all unmodified parts. In every licensed file, original copyright,
 * patent, trademark, and attribution notices must be preserved (excluding
 * notices that do not pertain to any part of the derivative works.) In every
 * licensed file changed, a notification must be added stating that changes have
 * been made to that file..." ("https://en.wikipedia.org/wiki/Apache_License")
 * 
    *
  • "Software can be freely used, modified and distributed in any environment * under this license." *
  • "A copy of the license must be included in the package." (→ see * refcodes-licensing dependency) *
  • "Changes to the source code of the software under the Apache license do * not have to be sent back to the licensor." *
  • "Own software that uses software under the Apache license does not have * to be under the Apache license." *
  • "Your own software may only be called Apache if the Apache Foundation has * given written permission." *
* (freely translated from "https://de.wikipedia.org/wiki/Apache_License") */ /* * $Id: AbstractEncryptionAlgorithm.java 2745 2013-06-25 21:16:10Z dfisher $ * * Copyright (C) 2003-2013 Virginia Tech. All rights reserved. * * SEE TEXT FOR MORE INFORMATION * * Author: Middleware Services Email: [email protected] Version: $Revision: 2745 * $ Updated: $Date: 2013-06-25 17:16:10 -0400 (Tue, 25 Jun 2013) $ */ package edu.vt.middleware.crypt; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.ShortBufferException; import edu.vt.middleware.crypt.util.Converter; /** * Base class for symmetric and asymmetric encryption algorithms. This class is * essentially a wrapper for the {@link Cipher} class. * * @author Middleware Services * * @version $Revision: 2745 $ */ public abstract class AbstractEncryptionAlgorithm extends AbstractAlgorithm implements EncryptionAlgorithm { /** Encryption/decription cipher. */ protected Cipher cipher; /** Mode used for encryption and decryption. */ protected String mode; /** Padding used for encryption and decryption. */ protected String padding; /** Either {@link Cipher#ENCRYPT_MODE} or {@link Cipher#DECRYPT_MODE}. */ protected int cipherMode; /** Key used for encryption or decryption. */ protected Key key; /** * Creates a new encryption algorithm that uses a cipher of the given name. * * @param cipherAlgorithm Cipher algorithm name. * @param cipherModeName Cipher mode. * @param cipherPadding Cipher padding method. */ protected AbstractEncryptionAlgorithm( final String cipherAlgorithm, final String cipherModeName, final String cipherPadding ) { this.algorithm = cipherAlgorithm; this.mode = cipherModeName; this.padding = cipherPadding; try { initCipher(); } catch ( CryptException e ) { throw new RuntimeException( "Error initializing cipher with name " + algorithm, e ); } } /** {@inheritDoc} */ @Override public String getMode() { return mode; } /** {@inheritDoc} */ @Override public String getPadding() { return padding; } /** {@inheritDoc} */ @Override public void setKey( final Key k ) { this.key = k; } /** {@inheritDoc} */ @Override public int getCipherMode() { return cipherMode; } /** {@inheritDoc} */ @Override public int getBlockSize() { return cipher.getBlockSize(); } /** {@inheritDoc} */ @Override public void initEncrypt() throws CryptException { init( Cipher.ENCRYPT_MODE ); } /** {@inheritDoc} */ @Override public void initDecrypt() throws CryptException { init( Cipher.DECRYPT_MODE ); } /** {@inheritDoc} */ @Override public byte[] encrypt( final byte[] plaintext ) throws CryptException { if ( cipherMode != Cipher.ENCRYPT_MODE ) { throw new CryptException( "Cipher is not in encryption mode." ); } return crypt( plaintext ); } /** {@inheritDoc} */ @Override public String encrypt( final byte[] plaintext, final Converter converter ) throws CryptException { return converter.fromBytes( encrypt( plaintext ) ); } /** {@inheritDoc} */ @Override public void encrypt( final InputStream in, final OutputStream out ) throws CryptException, IOException { if ( cipherMode != Cipher.ENCRYPT_MODE ) { throw new CryptException( "Cipher is not in encryption mode." ); } crypt( in, out ); } /** {@inheritDoc} */ @Override public byte[] decrypt( final byte[] ciphertext ) throws CryptException { if ( cipherMode != Cipher.DECRYPT_MODE ) { throw new CryptException( "Cipher is not in decryption mode." ); } return crypt( ciphertext ); } /** {@inheritDoc} */ @Override public byte[] decrypt( final String ciphertext, final Converter converter ) throws CryptException { return decrypt( converter.toBytes( ciphertext ) ); } /** {@inheritDoc} */ @Override public void decrypt( final InputStream in, final OutputStream out ) throws CryptException, IOException { if ( cipherMode != Cipher.DECRYPT_MODE ) { throw new CryptException( "Cipher is not in decryption mode." ); } crypt( in, out ); } /** {@inheritDoc} */ @Override public String toString() { final StringBuilder sb = new StringBuilder( 50 ); sb.append( algorithm ); sb.append( '/' ); sb.append( mode ); sb.append( '/' ); sb.append( padding ); return sb.toString(); } /** * Initializes the underlying {@link Cipher} object using * {@link #algorithm}, {@link #mode}, and {@link #padding}. * * @throws CryptException if the algorithm is not available from any * provider or if the provider is not available in the environment. */ protected void initCipher() throws CryptException { cipher = CryptProvider.getCipher( algorithm, mode, padding ); if ( randomProvider == null ) { randomProvider = new SecureRandom(); } } /** * Initializes {@link #cipher} for either encryption or decryption. * * @param encryptOrDecrypt Either Cipher.ENCRYPT_MODE * or Cipher.DECRYPT_MODE. * * @throws CryptException On cryptographic configuration errors. */ protected void init( final int encryptOrDecrypt ) throws CryptException { if ( cipher == null ) { throw new CryptException( "Cipher not initialized." ); } cipherMode = encryptOrDecrypt; try { final AlgorithmParameterSpec algSpec = getAlgorithmParameterSpec(); if ( algSpec != null ) { cipher.init( encryptOrDecrypt, key, algSpec, randomProvider ); } else { cipher.init( encryptOrDecrypt, key, randomProvider ); } } catch ( InvalidKeyException e ) { throw new CryptException( "Invalid key for " + this, e ); } catch ( InvalidAlgorithmParameterException e ) { throw new CryptException( "Invalid cipher parameters.", e ); } } /** * Based on current cipher mode, encrypts or decrypts the given input data. * * @param in Cipher input data. * * @return Cipher output data. * * @throws CryptException On encryption errors. */ protected byte[] crypt( final byte[] in ) throws CryptException { try { return cipher.doFinal( in ); } catch ( IllegalBlockSizeException e ) { throw new CryptException( "Bad block size.", e ); } catch ( BadPaddingException e ) { throw new CryptException( "Bad padding.", e ); } } /** * Based on current cipher mode, encrypts or decrypts the data in the given * input stream into resulting data in the output stream. * * @param in Input stream. * @param out Output stream. * * @throws CryptException On encryption errors. * @throws IOException On stream read/write errors. */ protected void crypt( final InputStream in, final OutputStream out ) throws CryptException, IOException { if ( in == null ) { throw new IllegalArgumentException( "Input stream cannot be null." ); } if ( out == null ) { throw new IllegalArgumentException( "Output stream cannot be null." ); } final byte[] inBuffer = new byte[getChunkSize()]; final byte[] outBuffer = new byte[getChunkSize() * 2]; int inCount; int outCount; try { while ( ( inCount = in.read( inBuffer ) ) > 0 ) { outCount = cipher.update( inBuffer, 0, inCount, outBuffer ); out.write( outBuffer, 0, outCount ); } final byte[] end = cipher.doFinal(); out.write( end ); } catch ( BadPaddingException e ) { throw new CryptException( "Bad padding.", e ); } catch ( IllegalBlockSizeException e ) { throw new CryptException( "Bad block size.", e ); } catch ( ShortBufferException e ) { throw new CryptException( "Output buffer is too small.", e ); } } /** * Gets the algorithm parameter specification for this algorithm. * * @return Algorithm parameter specification specific to this algorithm. */ protected abstract AlgorithmParameterSpec getAlgorithmParameterSpec(); /** * Gets the chunk size for buffers using in stream-based encryption and * decryption operations. * * @return Stream chunk size. */ protected abstract int getChunkSize(); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy