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

io.github.mmm.crypto.symmetric.key.spec.SymmetricKeySpecFactoryImplPbe Maven / Gradle / Ivy

package io.github.mmm.crypto.symmetric.key.spec;

import java.security.spec.KeySpec;

import javax.crypto.spec.PBEKeySpec;

import io.github.mmm.crypto.symmetric.key.SymmetricKeySpecFactory;

/**
 * Implementation of {@link SymmetricKeySpecFactory} for PBE ({@link PBEKeySpec}). For sufficient security
 * strength you should use a salt of {@code 20} bytes, a {@link #getKeyLength() key length} of {@code 256} bits (never
 * use less than {@code 128} bits) and a high number of iterations (e.g. {@code 65536}).
 *
 * @author Joerg Hohwiller (hohwille at users.sourceforge.net)
 * @since 1.0.0
 */
public class SymmetricKeySpecFactoryImplPbe implements SymmetricKeySpecFactory {

  private byte[] salt;

  private int iterationCount;

  private int keyLength;

  /**
   * The constructor.
   */
  public SymmetricKeySpecFactoryImplPbe() {

    this(null, 0, 0);
  }

  /**
   * The constructor.
   *
   * @param salt the {@link PBEKeySpec#getSalt() salt} or {@code null} for no salting.
   */
  public SymmetricKeySpecFactoryImplPbe(byte[] salt) {

    this(salt, 0, 0);
  }

  /**
   * The constructor.
   *
   * @param salt the {@link PBEKeySpec#getSalt() salt} or {@code null} for no salting.
   * @param iterationCount the {@link #getIterationCount() iteration count}.
   */
  public SymmetricKeySpecFactoryImplPbe(byte[] salt, int iterationCount) {

    this(salt, iterationCount, 0);
  }

  /**
   * The constructor.
   *
   * @param salt the {@link PBEKeySpec#getSalt() salt} or {@code null} for no salting.
   * @param iterationCount the {@link #getIterationCount() iteration count}.
   * @param keyLength the {@link #getKeyLength() key length}.
   */
  public SymmetricKeySpecFactoryImplPbe(byte[] salt, int iterationCount, int keyLength) {
    super();
    if (iterationCount < 0) {
      throw new IllegalArgumentException("iterationCount: " + iterationCount);
    }
    if (keyLength < 0) {
      throw new IllegalArgumentException("keyLength: " + keyLength);
    }
    if (salt == null) {
      if ((iterationCount != 0) || (keyLength != 0)) {
        throw new IllegalArgumentException("No iterationCount or keyLength can be specified if salt is null!");
      }
      this.salt = null;
    } else {
      this.salt = salt.clone();
    }
    this.keyLength = keyLength;
    this.iterationCount = iterationCount;
  }

  @Override
  public KeySpec createKeySpec(String password) {

    char[] pwd = password.toCharArray();
    if (this.salt == null) {
      assert (this.iterationCount == 0);
      assert (this.keyLength == 0);
      return new PBEKeySpec(pwd);
    } else if (this.keyLength <= 0) {
      return new PBEKeySpec(pwd, this.salt, this.iterationCount);
    } else {
      return new PBEKeySpec(pwd, this.salt, this.iterationCount, this.keyLength);
    }
  }

  /**
   * @return the {@link PBEKeySpec#getIterationCount() iteration count} or {@code 0} for no iterations.
   */
  public int getIterationCount() {

    return this.iterationCount;
  }

  /**
   * @return the {@link PBEKeySpec#getKeyLength() key length} in bits or {@code 0} if unspecified (to use defaults).
   */
  public int getKeyLength() {

    return this.keyLength;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy