/**
     * generate a PBE based key suitable for a MAC algorithm, the key size is chosen according the
     * MAC size, or the hashing algorithm, whichever is greater.
     */
    public static CipherParameters makePBEMacParameters(
        BCPBEKey pbeKey, AlgorithmParameterSpec spec) {
      if ((spec == null) || !(spec instanceof PBEParameterSpec)) {
        throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key.");
      }

      PBEParameterSpec pbeParam = (PBEParameterSpec) spec;
      PBEParametersGenerator generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest());
      byte[] key = pbeKey.getEncoded();
      CipherParameters param;

      if (pbeKey.shouldTryWrongPKCS12()) {
        key = new byte[2];
      }

      generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount());

      param = generator.generateDerivedMacParameters(pbeKey.getKeySize());

      for (int i = 0; i != key.length; i++) {
        key[i] = 0;
      }

      return param;
    }
Exemple #2
0
  static SecretKey generateSecretKeyForPKCS5Scheme2(
      String algorithm, char[] password, byte[] salt, int iterationCount) {
    PBEParametersGenerator generator = new PKCS5S2ParametersGenerator();

    generator.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), salt, iterationCount);

    return new SecretKeySpec(
        ((KeyParameter) generator.generateDerivedParameters(PEMUtilities.getKeySize(algorithm)))
            .getKey(),
        algorithm);
  }
Exemple #3
0
    private static byte[] convertPassword(int type, PBEKeySpec keySpec) {
      byte[] key;

      if (type == PKCS12) {
        key = PBEParametersGenerator.PKCS12PasswordToBytes(keySpec.getPassword());
      } else if (type == PKCS5S2_UTF8 || type == PKCS5S1_UTF8) {
        key = PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(keySpec.getPassword());
      } else {
        key = PBEParametersGenerator.PKCS5PasswordToBytes(keySpec.getPassword());
      }
      return key;
    }
 private static CipherParameters extractPBES2CipherParams(
     char[] password, PBES2Parameters pbeParams) {
   PBKDF2Params pbkdfParams =
       PBKDF2Params.getInstance(pbeParams.getKeyDerivationFunc().getParameters());
   int keySize = 192;
   if (pbkdfParams.getKeyLength() != null) {
     keySize = pbkdfParams.getKeyLength().intValue() * 8;
   }
   int iterationCount = pbkdfParams.getIterationCount().intValue();
   byte[] salt = pbkdfParams.getSalt();
   PBEParametersGenerator generator = new PKCS5S2ParametersGenerator();
   generator.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), salt, iterationCount);
   return generator.generateDerivedParameters(keySize);
 }
 private static void writePemEncrypted(
     BufferedWriter out, String pemHeader, byte[] encoding, CipherSpec cipher, char[] passwd)
     throws IOException {
   Cipher c = cipher.getCipher();
   byte[] iv = new byte[c.getBlockSize()];
   random.nextBytes(iv);
   byte[] salt = new byte[8];
   System.arraycopy(iv, 0, salt, 0, 8);
   OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator();
   pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(passwd), salt);
   KeyParameter param = (KeyParameter) pGen.generateDerivedParameters(cipher.getKeyLenInBits());
   SecretKey secretKey =
       new SecretKeySpec(
           param.getKey(), org.jruby.ext.openssl.Cipher.Algorithm.getAlgorithmBase(c));
   byte[] encData = null;
   try {
     c.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
     encData = c.doFinal(encoding);
   } catch (GeneralSecurityException gse) {
     throw new IOException("exception using cipher: " + gse.toString());
   }
   out.write(BEF_G + pemHeader + AFT);
   out.newLine();
   out.write("Proc-Type: 4,ENCRYPTED");
   out.newLine();
   out.write("DEK-Info: " + cipher.getOsslName() + ",");
   writeHexEncoded(out, iv);
   out.newLine();
   out.newLine();
   writeEncoded(out, encData);
   out.write(BEF_E + pemHeader + AFT);
   out.flush();
 }
 private static byte[] decrypt(byte[] decoded, String dekInfo, char[] passwd)
     throws IOException, GeneralSecurityException {
   if (passwd == null) {
     throw new IOException("Password is null, but a password is required");
   }
   StringTokenizer tknz = new StringTokenizer(dekInfo, ",");
   String algorithm = tknz.nextToken();
   byte[] iv = Hex.decode(tknz.nextToken());
   if (!CipherModule.isSupportedCipher(algorithm)) {
     throw new IOException("Unknown algorithm: " + algorithm);
   }
   String[] cipher = org.jruby.ext.openssl.Cipher.Algorithm.osslToJsse(algorithm);
   String realName = cipher[3];
   int[] lengths = org.jruby.ext.openssl.Cipher.Algorithm.osslKeyIvLength(algorithm);
   int keyLen = lengths[0];
   int ivLen = lengths[1];
   if (iv.length != ivLen) {
     throw new IOException("Illegal IV length");
   }
   byte[] salt = new byte[8];
   System.arraycopy(iv, 0, salt, 0, 8);
   OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator();
   pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(passwd), salt);
   KeyParameter param = (KeyParameter) pGen.generateDerivedParameters(keyLen * 8);
   SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(param.getKey(), realName);
   Cipher c = Cipher.getInstance(realName);
   c.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
   return c.doFinal(decoded);
 }
Exemple #7
0
    /**
     * generate a PBE based key suitable for a MAC algorithm, the key size is chosen according the
     * MAC size, or the hashing algorithm, whichever is greater.
     */
    public static CipherParameters makePBEMacParameters(
        PBEKeySpec keySpec, int type, int hash, int keySize) {
      PBEParametersGenerator generator = makePBEGenerator(type, hash);
      byte[] key;
      CipherParameters param;

      key = convertPassword(type, keySpec);

      generator.init(key, keySpec.getSalt(), keySpec.getIterationCount());

      param = generator.generateDerivedMacParameters(keySize);

      for (int i = 0; i != key.length; i++) {
        key[i] = 0;
      }

      return param;
    }
    /** construct a key and iv (if necessary) suitable for use with a Cipher. */
    public static CipherParameters makePBEParameters(
        BCPBEKey pbeKey, AlgorithmParameterSpec spec, String targetAlgorithm) {
      if ((spec == null) || !(spec instanceof PBEParameterSpec)) {
        throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key.");
      }

      PBEParameterSpec pbeParam = (PBEParameterSpec) spec;
      PBEParametersGenerator generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest());
      byte[] key = pbeKey.getEncoded();
      CipherParameters param;

      if (pbeKey.shouldTryWrongPKCS12()) {
        key = new byte[2];
      }

      generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount());

      if (pbeKey.getIvSize() != 0) {
        param = generator.generateDerivedParameters(pbeKey.getKeySize(), pbeKey.getIvSize());
      } else {
        param = generator.generateDerivedParameters(pbeKey.getKeySize());
      }

      if (targetAlgorithm.startsWith("DES")) {
        if (param instanceof ParametersWithIV) {
          KeyParameter kParam = (KeyParameter) ((ParametersWithIV) param).getParameters();

          DESParameters.setOddParity(kParam.getKey());
        } else {
          KeyParameter kParam = (KeyParameter) param;

          DESParameters.setOddParity(kParam.getKey());
        }
      }

      for (int i = 0; i != key.length; i++) {
        key[i] = 0;
      }

      return param;
    }
    /** construct a key and iv (if necessary) suitable for use with a Cipher. */
    public static CipherParameters makePBEParameters(
        PBEKeySpec keySpec, int type, int hash, int keySize, int ivSize) {
      PBEParametersGenerator generator = makePBEGenerator(type, hash);
      byte[] key;
      CipherParameters param;

      if (type == PKCS12) {
        key = PBEParametersGenerator.PKCS12PasswordToBytes(keySpec.getPassword());
      } else {
        key = PBEParametersGenerator.PKCS5PasswordToBytes(keySpec.getPassword());
      }

      generator.init(key, keySpec.getSalt(), keySpec.getIterationCount());

      if (ivSize != 0) {
        param = generator.generateDerivedParameters(keySize, ivSize);
      } else {
        param = generator.generateDerivedParameters(keySize);
      }

      for (int i = 0; i != key.length; i++) {
        key[i] = 0;
      }

      return param;
    }
  protected RecipientOperator getRecipientOperator(Recipient recipient)
      throws CMSException, IOException {
    PasswordRecipient pbeRecipient = (PasswordRecipient) recipient;
    AlgorithmIdentifier kekAlg = AlgorithmIdentifier.getInstance(info.getKeyEncryptionAlgorithm());
    ASN1Sequence kekAlgParams = (ASN1Sequence) kekAlg.getParameters();
    DERObjectIdentifier kekAlgName = DERObjectIdentifier.getInstance(kekAlgParams.getObjectAt(0));
    PBKDF2Params params =
        PBKDF2Params.getInstance(info.getKeyDerivationAlgorithm().getParameters());

    byte[] derivedKey;
    int keySize = ((Integer) KEYSIZES.get(kekAlgName)).intValue();

    if (pbeRecipient.getPasswordConversionScheme() == PasswordRecipient.PKCS5_SCHEME2) {
      PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();

      gen.init(
          PBEParametersGenerator.PKCS5PasswordToBytes(pbeRecipient.getPassword()),
          params.getSalt(),
          params.getIterationCount().intValue());

      derivedKey = ((KeyParameter) gen.generateDerivedParameters(keySize)).getKey();
    } else {
      PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();

      gen.init(
          PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(pbeRecipient.getPassword()),
          params.getSalt(),
          params.getIterationCount().intValue());

      derivedKey = ((KeyParameter) gen.generateDerivedParameters(keySize)).getKey();
    }

    return pbeRecipient.getRecipientOperator(
        AlgorithmIdentifier.getInstance(kekAlg.getParameters()),
        messageAlgorithm,
        derivedKey,
        info.getEncryptedKey().getOctets());
  }
Exemple #11
0
  private static SecretKey getKey(
      char[] password, String algorithm, int keyLength, byte[] salt, boolean des2) {
    OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator();

    pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), salt);

    KeyParameter keyParam;
    keyParam = (KeyParameter) pGen.generateDerivedParameters(keyLength * 8);
    byte[] key = keyParam.getKey();
    if (des2 && key.length >= 24) {
      // For DES2, we must copy first 8 bytes into the last 8 bytes.
      System.arraycopy(key, 0, key, 16, 8);
    }
    return new javax.crypto.spec.SecretKeySpec(key, algorithm);
  }