<commit_before>/*
 * $Id: EncryptorBean.java 988 2008-12-30 08:51:13Z lhoriman $
 * $URL: http://subetha.tigris.org/svn/subetha/branches/resin/core/src/org/subethamail/core/admin/EncryptorBean.java $
 */

package org.subethamail.core.admin;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.annotation.PostConstruct;
import javax.context.ApplicationScoped;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.ejb.EJBException;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.subethamail.common.NotFoundException;
import org.subethamail.core.admin.i.Encryptor;
import org.subethamail.core.admin.i.ExpiredException;
import org.subethamail.core.util.SubEtha;
import org.subethamail.core.util.SubEthaEntityManager;
import org.subethamail.entity.Config;

/**
 * Performs encryption and decryption using a constant key.  The
 * key is set as a config value.  If the key doesn't exist when
 * the service is started, a random key is generated.
 * 
 * The BootstrapperBean is a dependency that must be init'd first.
 * 
 * Note that this bean does NOT have a remote interface.
 * 
 * @author <NAME>
 * @author <NAME>
 */

@ApplicationScoped
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EncryptorBean implements Encryptor
{
	/** */
	private final static Logger log = LoggerFactory.getLogger(EncryptorBean.class);
	
	/**
	 * The name of the config value that holds the current encryption key.
	 * The actual config value will be a base64-encoded string. 
	 */
	private static final String KEY_CONFIG_ID = "cipherKey";
	
	/**
	 * The number of bytes in a key.
	 */
	private static final int KEY_LENGTH = 16;
	
	
	/**
	 * An initial vector for encoding.  The content is more or less irrelevant.
	 */
	private static final byte[] IV = new byte[KEY_LENGTH];
	static
	{
		for (int i=0; i<KEY_LENGTH; i++)
			IV[i] = (byte)(i+10);
	}

	/** */
	@SubEtha
	protected SubEthaEntityManager em;
	
	/* */
	@PostConstruct
	public void start() throws Exception
	{
		// If we don't already have a key, generate one
		try
		{
			Config cfg = this.em.get(Config.class, KEY_CONFIG_ID);
			
			// Might as well sanity check it
			String value = (String)cfg.getValue();
			
			if (value == null || value.length() == 0)
				cfg.setValue(this.generateKey());
		}
		catch (NotFoundException ex)
		{
			if(log.isInfoEnabled()) log.info("Creating new cypher key for Encryptor, and storing it in the database");
			Config cfg = new Config(KEY_CONFIG_ID, this.generateKey());
			this.em.persist(cfg);
		}
	}
	
	/**
	 * Randomly generates a new, base64-encoded key.  The raw key
	 * will be 16 bytes long.
	 */
	protected String generateKey()
	{
		byte[] generated = new byte[KEY_LENGTH];

		Random rnd = new SecureRandom();
		rnd.nextBytes(generated);
		
		return new String(Base64.encodeBase64(generated));
	}<commit_msg>Minor documentation improvement.<commit_after>/*
 * $Id: EncryptorBean.java 988 2008-12-30 08:51:13Z lhoriman $
 * $URL: http://subetha.tigris.org/svn/subetha/branches/resin/core/src/org/subethamail/core/admin/EncryptorBean.java $
 */

package org.subethamail.core.admin;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.annotation.PostConstruct;
import javax.context.ApplicationScoped;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.ejb.EJBException;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.subethamail.common.NotFoundException;
import org.subethamail.core.admin.i.Encryptor;
import org.subethamail.core.admin.i.ExpiredException;
import org.subethamail.core.util.SubEtha;
import org.subethamail.core.util.SubEthaEntityManager;
import org.subethamail.entity.Config;

/**
 * Performs encryption and decryption using a constant key.  The
 * key is set as a config value.  If the key doesn't exist when
 * the service is started, a random key is generated.
 * 
 * Note that this bean does NOT have a remote interface.
 * 
 * @author <NAME>
 * @author <NAME>ernandez
 */
@ApplicationScoped
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EncryptorBean implements Encryptor
{
	/** */
	private final static Logger log = LoggerFactory.getLogger(EncryptorBean.class);
	
	/**
	 * The name of the config value that holds the current encryption key.
	 * The actual config value will be a base64-encoded string. 
	 */
	private static final String KEY_CONFIG_ID = "cipherKey";
	
	/**
	 * The number of bytes in a key.
	 */
	private static final int KEY_LENGTH = 16;
	
	
	/**
	 * An initial vector for encoding.  The content is more or less irrelevant.
	 */
	private static final byte[] IV = new byte[KEY_LENGTH];
	static
	{
		for (int i=0; i<KEY_LENGTH; i++)
			IV[i] = (byte)(i+10);
	}

	/** */
	@SubEtha
	protected SubEthaEntityManager em;
	
	/* */
	@PostConstruct
	public void start() throws Exception
	{
		// If we don't already have a key, generate one
		try
		{
			Config cfg = this.em.get(Config.class, KEY_CONFIG_ID);
			
			// Might as well sanity check it
			String value = (String)cfg.getValue();
			
			if (value == null || value.length() == 0)
				cfg.setValue(this.generateKey());
		}
		catch (NotFoundException ex)
		{
			if (log.isInfoEnabled()) log.info("Creating new cypher key for Encryptor, and storing it in the database");
			Config cfg = new Config(KEY_CONFIG_ID, this.generateKey());
			this.em.persist(cfg);
		}
	}
	
	/**
	 * Randomly generates a new, base64-encoded key.  The raw key
	 * will be 16 bytes long.
	 */
	protected String generateKey()
	{
		byte[] generated = new byte[KEY_LENGTH];

		Random rnd = new SecureRandom();
		rnd.nextBytes(generated);
		
		return new String(Base64.encodeBase64(generated));
	}
{'fraction_non_alphanumeric': 0.10915915915915916, 'fraction_numerical': 0.011111111111111112, 'mean_word_length': 4.171583850931677, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '819758', 'n_tokens_mistral': 2281, 'n_tokens_neox': 2082, 'n_words': 577}