/**
   * Returns an instance of a padding algorithm given its name.
   *
   * @param prng the case-insensitive name of the PRNG.
   * @return an instance of the pseudo-random number generator.
   * @exception InternalError if the implementation does not pass its self- test.
   */
  public static final IRandom getInstance(String prng) {
    if (prng == null) {
      return null;
    }

    prng = prng.trim();
    IRandom result = null;
    if (prng.equalsIgnoreCase(ARCFOUR_PRNG) || prng.equalsIgnoreCase(RC4_PRNG)) {
      result = new ARCFour();
    } else if (prng.equalsIgnoreCase(ICM_PRNG)) {
      result = new ICMGenerator();
    } else if (prng.equalsIgnoreCase(MD_PRNG)) {
      result = new MDGenerator();
    } else if (prng.equalsIgnoreCase(UMAC_PRNG)) {
      result = new UMacGenerator();
    } else if (prng.toLowerCase().startsWith(PBKDF2_PRNG_PREFIX)) {
      String macName = prng.substring(PBKDF2_PRNG_PREFIX.length());
      IMac mac = MacFactory.getInstance(macName);
      if (mac == null) {
        return null;
      }
      result = new PBKDF2(mac);
    }

    return result;
  }
  private IMac getMac(char[] password) throws MalformedKeyringException {
    if (!properties.containsKey("salt")) {
      throw new MalformedKeyringException("no salt");
    }
    byte[] salt = Util.toBytesFromString(properties.get("salt"));
    IMac mac = MacFactory.getInstance(properties.get("mac"));
    if (mac == null) {
      throw new MalformedKeyringException("no such mac: " + properties.get("mac"));
    }
    int keylen = mac.macSize();
    int maclen = 0;
    if (!properties.containsKey("maclen")) {
      throw new MalformedKeyringException("no MAC length");
    }
    try {
      maclen = Integer.parseInt(properties.get("maclen"));
    } catch (NumberFormatException nfe) {
      throw new MalformedKeyringException("bad MAC length");
    }

    HashMap pbAttr = new HashMap();
    pbAttr.put(IPBE.PASSWORD, password);
    pbAttr.put(IPBE.SALT, salt);
    pbAttr.put(IPBE.ITERATION_COUNT, ITERATION_COUNT);
    IRandom kdf = PRNGFactory.getInstance("PBKDF2-HMAC-SHA");
    kdf.init(pbAttr);

    byte[] dk = new byte[keylen];
    try {
      kdf.nextBytes(dk, 0, keylen);
    } catch (LimitReachedException shouldNotHappen) {
      throw new Error(shouldNotHappen.toString());
    }

    HashMap macAttr = new HashMap();
    macAttr.put(IMac.MAC_KEY_MATERIAL, dk);
    macAttr.put(IMac.TRUNCATED_SIZE, new Integer(maclen));
    try {
      mac.init(macAttr);
    } catch (InvalidKeyException shouldNotHappen) {
      throw new Error(shouldNotHappen.toString());
    }
    return mac;
  }