org.apache.poi.EncryptedDocumentException Java Examples

The following examples show how to use org.apache.poi.EncryptedDocumentException. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ExcelServiceImpl.java    From molgenis with GNU Lesser General Public License v3.0 6 votes vote down vote up
@Override
public List<Sheet> buildExcelSheetsFromFile(File file) throws EmptySheetException {
  List<Sheet> sheets = newArrayList();
  try (Workbook workbook = WorkbookFactory.create(file)) {
    int numberOfSheets = workbook.getNumberOfSheets();

    for (int index = 0; index < numberOfSheets; index++) {
      Sheet sheet = workbook.getSheetAt(index);
      if (sheet.getPhysicalNumberOfRows() == 0) {
        throw new EmptySheetException("Sheet [" + sheet.getSheetName() + "] is empty");
      } else if (sheet.getPhysicalNumberOfRows() == 1) {
        throw new MolgenisDataException(
            "Header was found, but no data is present in sheet [" + sheet.getSheetName() + "]");
      } else {
        sheets.add(sheet);
      }
    }

  } catch (IOException | EncryptedDocumentException ex) {
    LOG.error(ex.getLocalizedMessage());
    throw new MolgenisDataException("Could not create excel workbook from file");
  }
  return sheets;
}
 
Example #2
Source File: StandardEncryptor.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void processPOIFSWriterEvent(POIFSWriterEvent event) {
    try {
        LittleEndianOutputStream leos = new LittleEndianOutputStream(event.getStream());

        // StreamSize (8 bytes): An unsigned integer that specifies the number of bytes used by data 
        // encrypted within the EncryptedData field, not including the size of the StreamSize field. 
        // Note that the actual size of the \EncryptedPackage stream (1) can be larger than this 
        // value, depending on the block size of the chosen encryption algorithm
        leos.writeLong(countBytes);

        FileInputStream fis = new FileInputStream(fileOut);
        try {
            IOUtils.copy(fis, leos);
        } finally {
            fis.close();
        }
        if (!fileOut.delete()) {
            logger.log(POILogger.ERROR, "Can't delete temporary encryption file: "+fileOut);
        }

        leos.close();
    } catch (IOException e) {
        throw new EncryptedDocumentException(e);
    }
}
 
Example #3
Source File: BinaryRC4Encryptor.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void confirmPassword(String password, byte keySpec[],
        byte keySalt[], byte verifier[], byte verifierSalt[],
        byte integritySalt[]) {
    BinaryRC4EncryptionVerifier ver = (BinaryRC4EncryptionVerifier)getEncryptionInfo().getVerifier();
    ver.setSalt(verifierSalt);
    SecretKey skey = BinaryRC4Decryptor.generateSecretKey(password, ver);
    setSecretKey(skey);
    try {
        Cipher cipher = BinaryRC4Decryptor.initCipherForBlock(null, 0, getEncryptionInfo(), skey, Cipher.ENCRYPT_MODE);
        byte encryptedVerifier[] = new byte[16];
        cipher.update(verifier, 0, 16, encryptedVerifier);
        ver.setEncryptedVerifier(encryptedVerifier);
        HashAlgorithm hashAlgo = ver.getHashAlgorithm();
        MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo);
        byte calcVerifierHash[] = hashAlg.digest(verifier);
        byte encryptedVerifierHash[] = cipher.doFinal(calcVerifierHash);
        ver.setEncryptedVerifierHash(encryptedVerifierHash);
    } catch (GeneralSecurityException e) {
        throw new EncryptedDocumentException("Password confirmation failed", e);
    }
}
 
Example #4
Source File: BinaryRC4Decryptor.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@Override
public boolean verifyPassword(String password) {
    EncryptionVerifier ver = getEncryptionInfo().getVerifier();
    SecretKey skey = generateSecretKey(password, ver);
    try {
        Cipher cipher = initCipherForBlock(null, 0, getEncryptionInfo(), skey, Cipher.DECRYPT_MODE);
        byte encryptedVerifier[] = ver.getEncryptedVerifier();
        byte verifier[] = new byte[encryptedVerifier.length];
        cipher.update(encryptedVerifier, 0, encryptedVerifier.length, verifier);
        setVerifier(verifier);
        byte encryptedVerifierHash[] = ver.getEncryptedVerifierHash();
        byte verifierHash[] = cipher.doFinal(encryptedVerifierHash);
        HashAlgorithm hashAlgo = ver.getHashAlgorithm();
        MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo);
        byte calcVerifierHash[] = hashAlg.digest(verifier);
        if (Arrays.equals(calcVerifierHash, verifierHash)) {
            setSecretKey(skey);
            return true;
        }
    } catch (GeneralSecurityException e) {
        throw new EncryptedDocumentException(e);
    }
    return false;
}
 
Example #5
Source File: EncryptionInfo.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Constructs an EncryptionInfo from scratch
 *
 * @param encryptionMode see {@link EncryptionMode} for values, {@link EncryptionMode#cryptoAPI} is for
 *   internal use only, as it's record based
 * @param cipherAlgorithm
 * @param hashAlgorithm
 * @param keyBits
 * @param blockSize
 * @param chainingMode
 * 
 * @throws EncryptedDocumentException if the given parameters mismatch, e.g. only certain combinations
 *   of keyBits, blockSize are allowed for a given {@link CipherAlgorithm}
 */
public EncryptionInfo(
        EncryptionMode encryptionMode
      , CipherAlgorithm cipherAlgorithm
      , HashAlgorithm hashAlgorithm
      , int keyBits
      , int blockSize
      , ChainingMode chainingMode
  ) {
    this.encryptionMode = encryptionMode; 
    versionMajor = encryptionMode.versionMajor;
    versionMinor = encryptionMode.versionMinor;
    encryptionFlags = encryptionMode.encryptionFlags;

    EncryptionInfoBuilder eib;
    try {
        eib = getBuilder(encryptionMode);
    } catch (Exception e) {
        throw new EncryptedDocumentException(e);
    }
    
    eib.initialize(this, cipherAlgorithm, hashAlgorithm, keyBits, blockSize, chainingMode);
}
 
Example #6
Source File: CryptoAPIEncryptionHeader.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void setKeySize(int keyBits) {
    // Microsoft Base Cryptographic Provider is limited up to 40 bits
    // http://msdn.microsoft.com/en-us/library/windows/desktop/aa375599(v=vs.85).aspx
    boolean found = false;
    for (int size : getCipherAlgorithm().allowedKeySize) {
        if (size == keyBits) {
            found = true;
            break;
        }
    }
    if (!found) {
        throw new EncryptedDocumentException("invalid keysize "+keyBits+" for cipher algorithm "+getCipherAlgorithm());
    }
    super.setKeySize(keyBits);
    if (keyBits > 40) {
        setCspName("Microsoft Enhanced Cryptographic Provider v1.0");
    } else {
        setCspName(CipherProvider.rc4.cipherProviderName);
    }
}
 
Example #7
Source File: CryptoAPIEncryptor.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void confirmPassword(String password, byte keySpec[],
        byte keySalt[], byte verifier[], byte verifierSalt[],
        byte integritySalt[]) {
    assert(verifier != null && verifierSalt != null);
    CryptoAPIEncryptionVerifier ver = (CryptoAPIEncryptionVerifier)getEncryptionInfo().getVerifier();
    ver.setSalt(verifierSalt);
    SecretKey skey = CryptoAPIDecryptor.generateSecretKey(password, ver);
    setSecretKey(skey);
    try {
        Cipher cipher = initCipherForBlock(null, 0);
        byte encryptedVerifier[] = new byte[verifier.length];
        cipher.update(verifier, 0, verifier.length, encryptedVerifier);
        ver.setEncryptedVerifier(encryptedVerifier);
        HashAlgorithm hashAlgo = ver.getHashAlgorithm();
        MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo);
        byte calcVerifierHash[] = hashAlg.digest(verifier);
        byte encryptedVerifierHash[] = cipher.doFinal(calcVerifierHash);
        ver.setEncryptedVerifierHash(encryptedVerifierHash);
    } catch (GeneralSecurityException e) {
        throw new EncryptedDocumentException("Password confirmation failed", e);
    }
}
 
Example #8
Source File: CryptoAPIDecryptor.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@Override
public boolean verifyPassword(String password) {
    EncryptionVerifier ver = getEncryptionInfo().getVerifier();
    SecretKey skey = generateSecretKey(password, ver);
    try {
        Cipher cipher = initCipherForBlock(null, 0, getEncryptionInfo(), skey, Cipher.DECRYPT_MODE);
        byte encryptedVerifier[] = ver.getEncryptedVerifier();
        byte verifier[] = new byte[encryptedVerifier.length];
        cipher.update(encryptedVerifier, 0, encryptedVerifier.length, verifier);
        setVerifier(verifier);
        byte encryptedVerifierHash[] = ver.getEncryptedVerifierHash();
        byte verifierHash[] = cipher.doFinal(encryptedVerifierHash);
        HashAlgorithm hashAlgo = ver.getHashAlgorithm();
        MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo);
        byte calcVerifierHash[] = hashAlg.digest(verifier);
        if (Arrays.equals(calcVerifierHash, verifierHash)) {
            setSecretKey(skey);
            return true;
        }
    } catch (GeneralSecurityException e) {
        throw new EncryptedDocumentException(e);
    }
    return false;
}
 
Example #9
Source File: DataSpaceMapUtils.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
public static String readUnicodeLPP4(LittleEndianInput is) {
    int length = is.readInt();
    if (length%2 != 0) {
        throw new EncryptedDocumentException(
            "UNICODE-LP-P4 structure is a multiple of 4 bytes. "
            + "If Padding is present, it MUST be exactly 2 bytes long");
    }
    
    String result = StringUtil.readUnicodeLE(is, length/2);
    if (length%4==2) {
        // Padding (variable): A set of bytes that MUST be of the correct size such that the size of the 
        // UNICODE-LP-P4 structure is a multiple of 4 bytes. If Padding is present, it MUST be exactly 
        // 2 bytes long, and each byte MUST be 0x00.            
        is.readShort();
    }
    
    return result;
}
 
Example #10
Source File: FilePassRecord.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
public FilePassRecord(RecordInputStream in) {
	encryptionType = in.readUShort();
	
	EncryptionMode preferredMode;
       switch (encryptionType) {
           case ENCRYPTION_XOR:
               preferredMode = EncryptionMode.xor;
               break;
           case ENCRYPTION_OTHER:
               preferredMode = EncryptionMode.cryptoAPI;
               break;
           default:
               throw new EncryptedDocumentException("invalid encryption type");
       }
	
	try {
           encryptionInfo = new EncryptionInfo(in, preferredMode);
       } catch (IOException e) {
           throw new EncryptedDocumentException(e);
       }
}
 
Example #11
Source File: RecordFactoryInputStream.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
public RecordInputStream createDecryptingStream(InputStream original) {
	FilePassRecord fpr = _filePassRec;
	String userPassword = Biff8EncryptionKey.getCurrentUserPassword();
	if (userPassword == null) {
	    userPassword = Decryptor.DEFAULT_PASSWORD;
	}

	EncryptionInfo info = fpr.getEncryptionInfo();
          try {
              if (!info.getDecryptor().verifyPassword(userPassword)) {
                  throw new EncryptedDocumentException(
                          (Decryptor.DEFAULT_PASSWORD.equals(userPassword) ? "Default" : "Supplied")
                          + " password is invalid for salt/verifier/verifierHash");
              }
          } catch (GeneralSecurityException e) {
              throw new EncryptedDocumentException(e);
          }

	return new RecordInputStream(original, info, _initialRecordsSize);
}
 
Example #12
Source File: FilePassRecord.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private FilePassRecord(FilePassRecord other) {
    encryptionType = other.encryptionType;
       try {
           encryptionInfo = other.encryptionInfo.clone();
       } catch (CloneNotSupportedException e) {
           throw new EncryptedDocumentException(e);
       }
}
 
Example #13
Source File: ExcelSheetsExtractorTests.java    From vividus with Apache License 2.0 5 votes vote down vote up
@DataProvider
public static Object[][] exceptionDataProvider()
{
    // @formatter:off
    return new Object[][] {
        { EncryptedDocumentException.class },
        { IOException.class }};
    // @formatter:on
}
 
Example #14
Source File: Data.java    From poi-mail-merge with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Read the given file either as .csv or .xls/.xlsx file, depending
 * on the file-extension.
 *
 * @param dataFile The merge-file to read. Can have extension .csv, .xls or .xlsx
 * @throws IOException If an error occurs while reading the file
 * @throws EncryptedDocumentException If the document is encrypted (passwords are not supported currently)
 * @throws InvalidFormatException If the .xls/.xlsx file cannot be read due to a file-format error
 */
public void read(File dataFile) throws IOException, EncryptedDocumentException, InvalidFormatException {
    // read the lines from the data-file
    if(FilenameUtils.getExtension(dataFile.getName()).equalsIgnoreCase("csv")) {
        readCSVFile(dataFile);
    } else {
        readExcelFile(dataFile);
    }

    removeEmptyLines();
}
 
Example #15
Source File: ExcelImportService.java    From fredbet with Creative Commons Attribution Share Alike 4.0 International 5 votes vote down vote up
public List<Match> importFromExcel(File file) {
	try (InputStream inp = new FileInputStream(file)) {
		return importFromInputStream(inp);
	} catch (IOException | EncryptedDocumentException | InvalidFormatException e) {
		throw new ExcelReadingException(e.getMessage(), e);
	}
}
 
Example #16
Source File: ExcelImportService.java    From fredbet with Creative Commons Attribution Share Alike 4.0 International 5 votes vote down vote up
public List<Match> importFromExcel(byte[] bytes) {
	try (InputStream inp = new ByteArrayInputStream(bytes)) {
		return importFromInputStream(inp);
	} catch (IOException | EncryptedDocumentException | InvalidFormatException e) {
		throw new ExcelReadingException(e.getMessage(), e);
	}
}
 
Example #17
Source File: ExcelSheetsExtractor.java    From vividus with Apache License 2.0 5 votes vote down vote up
public ExcelSheetsExtractor(String path) throws WorkbookParsingException
{
    try (Workbook wb = WorkbookFactory
            .create(ResourceUtils.loadFile(this.getClass(), StringUtils.prependIfMissing(path, "/"))))
    {
        sheets = getAllSheetsFromWorkbook(wb);
    }
    catch (EncryptedDocumentException | IOException e)
    {
        throw new WorkbookParsingException(e);
    }
}
 
Example #18
Source File: FilePassRecord.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@SuppressWarnings("resource")
   @Override
   public void serialize(LittleEndianOutput out) {
       out.writeShort(encryptionType);

       byte data[] = new byte[1024];
       LittleEndianByteArrayOutputStream bos = new LittleEndianByteArrayOutputStream(data, 0); // NOSONAR

       switch (encryptionInfo.getEncryptionMode()) {
           case xor:
               ((XOREncryptionHeader)encryptionInfo.getHeader()).write(bos);
               ((XOREncryptionVerifier)encryptionInfo.getVerifier()).write(bos);
               break;
           case binaryRC4:
               out.writeShort(encryptionInfo.getVersionMajor());
               out.writeShort(encryptionInfo.getVersionMinor());
               ((BinaryRC4EncryptionHeader)encryptionInfo.getHeader()).write(bos);
               ((BinaryRC4EncryptionVerifier)encryptionInfo.getVerifier()).write(bos);
               break;
           case cryptoAPI:
               out.writeShort(encryptionInfo.getVersionMajor());
               out.writeShort(encryptionInfo.getVersionMinor());
               out.writeInt(encryptionInfo.getEncryptionFlags());
               ((CryptoAPIEncryptionHeader)encryptionInfo.getHeader()).write(bos);
               ((CryptoAPIEncryptionVerifier)encryptionInfo.getVerifier()).write(bos);
               break;
           default:
               throw new EncryptedDocumentException("not supported");
       }

       out.write(data, 0, bos.getWriteIndex());
}
 
Example #19
Source File: CryptoFunctions.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
public static Mac getMac(HashAlgorithm hashAlgorithm) {
    try {
        if (hashAlgorithm.needsBouncyCastle) {
            registerBouncyCastle();
            return Mac.getInstance(hashAlgorithm.jceHmacId, "BC");
        } else {
            return Mac.getInstance(hashAlgorithm.jceHmacId);
        }
    } catch (GeneralSecurityException e) {
        throw new EncryptedDocumentException("hmac algo not supported", e);
    }
}
 
Example #20
Source File: CryptoFunctions.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
public static MessageDigest getMessageDigest(HashAlgorithm hashAlgorithm) {
    try {
        if (hashAlgorithm.needsBouncyCastle) {
            registerBouncyCastle();
            return MessageDigest.getInstance(hashAlgorithm.jceId, "BC");
        } else {
            return MessageDigest.getInstance(hashAlgorithm.jceId);
        }
    } catch (GeneralSecurityException e) {
        throw new EncryptedDocumentException("hash algo not supported", e);
    }
}
 
Example #21
Source File: CryptoFunctions.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Generalized method for read and write protection hash generation.
 * The difference is, read protection uses the order iterator then hash in the hash loop, whereas write protection
 * uses first the last hash value and then the current iterator value
 *
 * @param password
 * @param hashAlgorithm
 * @param salt
 * @param spinCount
 * @param iteratorFirst if true, the iterator is hashed before the n-1 hash value,
 *        if false the n-1 hash value is applied first
 * @return the hashed password
 */
public static byte[] hashPassword(String password, HashAlgorithm hashAlgorithm, byte salt[], int spinCount, boolean iteratorFirst) {
    // If no password was given, use the default
    if (password == null) {
        password = Decryptor.DEFAULT_PASSWORD;
    }
    
    MessageDigest hashAlg = getMessageDigest(hashAlgorithm);
    
    hashAlg.update(salt);
    byte[] hash = hashAlg.digest(StringUtil.getToUnicodeLE(password));
    byte[] iterator = new byte[LittleEndianConsts.INT_SIZE];

    byte[] first = (iteratorFirst ? iterator : hash);
    byte[] second = (iteratorFirst ? hash : iterator);
    
    try {
        for (int i = 0; i < spinCount; i++) {
            LittleEndian.putInt(iterator, 0, i);
            hashAlg.reset();
            hashAlg.update(first);
            hashAlg.update(second);
            hashAlg.digest(hash, 0, hash.length); // don't create hash buffer everytime new
        }
    } catch (DigestException e) {
        throw new EncryptedDocumentException("error in password hashing");
    }
    
    return hash;
}
 
Example #22
Source File: ExcelToQuestionUtils.java    From Exam-Online with Apache License 2.0 5 votes vote down vote up
public static List<Question> readQuestions(InputStream inputStream) 
		throws EncryptedDocumentException, InvalidFormatException, IOException {
	
	Workbook workbook = WorkbookFactory.create(inputStream);
	List<Question> questions = readQuestions(workbook.getSheetAt(0)); 
	workbook.close();
	return questions;
}
 
Example #23
Source File: DataSpaceMapUtils.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
public static DocumentEntry createEncryptionEntry(DirectoryEntry dir, String path, EncryptionRecord out) throws IOException {
    String parts[] = path.split("/");
    for (int i=0; i<parts.length-1; i++) {
        dir = dir.hasEntry(parts[i])
            ? (DirectoryEntry)dir.getEntry(parts[i])
            : dir.createDirectory(parts[i]);
    }
    
    final byte buf[] = new byte[5000];        
    LittleEndianByteArrayOutputStream bos = new LittleEndianByteArrayOutputStream(buf, 0);
    out.write(bos);
    
    String fileName = parts[parts.length-1];
    
    if (dir.hasEntry(fileName)) {
        dir.getEntry(fileName).delete();
    }
    
    return dir.createDocument(fileName, bos.getWriteIndex(), new POIFSWriterListener(){
        public void processPOIFSWriterEvent(POIFSWriterEvent event) {
            try {
                event.getStream().write(buf, 0, event.getLimit());
            } catch (IOException e) {
                throw new EncryptedDocumentException(e);
            }
        }
    });
}
 
Example #24
Source File: Decryptor.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
public static Decryptor getInstance(EncryptionInfo info) {
    Decryptor d = info.getDecryptor();
    if (d == null) {
        throw new EncryptedDocumentException("Unsupported version");
    }
    return d;
}
 
Example #25
Source File: ChunkedCipherInputStream.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private int read(byte[] b, int off, int len, boolean readPlain) throws IOException {
    int total = 0;

    if (available() <= 0) {
        return -1;
    }

    final int chunkMask = getChunkMask();
    while (len > 0) {
        if (!chunkIsValid) {
            try {
                nextChunk();
                chunkIsValid = true;
            } catch (GeneralSecurityException e) {
                throw new EncryptedDocumentException(e.getMessage(), e);
            }
        }
        int count = (int)(chunk.length - (pos & chunkMask));
        int avail = available();
        if (avail == 0) {
            return total;
        }
        count = Math.min(avail, Math.min(count, len));

        System.arraycopy(readPlain ? plain : chunk, (int)(pos & chunkMask), b, off, count);

        off += count;
        len -= count;
        pos += count;
        if ((pos & chunkMask) == 0) {
            chunkIsValid = false;
        }
        total += count;
    }

    return total;
}
 
Example #26
Source File: ExcelToQuestionUtils.java    From Exam-Online with Apache License 2.0 5 votes vote down vote up
public static void main(String[] args) throws EncryptedDocumentException, InvalidFormatException, IOException {
	File file = new File("e://test.xls");
	List<Question> questions = readQuestions(file);
	questions.forEach(q -> {
		System.out.println(q);
	});
}
 
Example #27
Source File: CryptoAPIDocumentInputStream.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public synchronized int read(byte b[], int off, int len) {
    int readLen = super.read(b, off, len);
    if (readLen ==-1) {
        return -1;
    }
    try {
        cipher.update(b, off, readLen, b, off);
    } catch (ShortBufferException e) {
        throw new EncryptedDocumentException(e);
    }
    return readLen;
}
 
Example #28
Source File: CryptoAPIDocumentOutputStream.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void write(byte[] b, int off, int len) {
    try {
        cipher.update(b, off, len, b, off);
        super.write(b, off, len);
    } catch (Exception e) {
        throw new EncryptedDocumentException(e);
    }
}
 
Example #29
Source File: CryptoAPIDocumentOutputStream.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void write(int b) {
    try {
        oneByte[0] = (byte)b;
        cipher.update(oneByte, 0, 1, oneByte, 0);
        super.write(oneByte);
    } catch (Exception e) {
        throw new EncryptedDocumentException(e);
    }
}
 
Example #30
Source File: CryptoFunctions.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@SuppressWarnings("unchecked")
public static void registerBouncyCastle() {
    if (Security.getProvider("BC") != null) {
        return;
    }
    
    try {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        String bcProviderName = "org.bouncycastle.jce.provider.BouncyCastleProvider";
        Class<Provider> clazz = (Class<Provider>)cl.loadClass(bcProviderName);
        Security.addProvider(clazz.newInstance());
    } catch (Exception e) {
        throw new EncryptedDocumentException("Only the BouncyCastle provider supports your encryption settings - please add it to the classpath.", e);
    }
}