@Test
public void testStandardEncryption() throws Exception {
File file = POIDataSamples.getDocumentInstance().getFile("bug53475-password-is-solrcell.docx");
String pass = "solrcell";
NPOIFSFileSystem nfs = new NPOIFSFileSystem(file);
// Check the encryption details
EncryptionInfo infoExpected = new EncryptionInfo(nfs);
Decryptor d = Decryptor.getInstance(infoExpected);
boolean passed = d.verifyPassword(pass);
assertTrue("Unable to process: document is encrypted", passed);
// extract the payload
ByteArrayOutputStream bos = new ByteArrayOutputStream();
InputStream is = d.getDataStream(nfs);
IOUtils.copy(is, bos);
is.close();
nfs.close();
byte payloadExpected[] = bos.toByteArray();
// check that same verifier/salt lead to same hashes
byte verifierSaltExpected[] = infoExpected.getVerifier().getSalt();
byte verifierExpected[] = d.getVerifier();
byte keySpec[] = d.getSecretKey().getEncoded();
byte keySalt[] = infoExpected.getHeader().getKeySalt();
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo infoActual = new EncryptionInfo(
fs, EncryptionMode.standard
, infoExpected.getVerifier().getCipherAlgorithm()
, infoExpected.getVerifier().getHashAlgorithm()
, infoExpected.getHeader().getKeySize()
, infoExpected.getHeader().getBlockSize()
, infoExpected.getVerifier().getChainingMode()
);
Encryptor e = Encryptor.getInstance(infoActual);
e.confirmPassword(pass, keySpec, keySalt, verifierExpected, verifierSaltExpected, null);
assertThat(infoExpected.getVerifier().getEncryptedVerifier(), equalTo(infoActual.getVerifier().getEncryptedVerifier()));
assertThat(infoExpected.getVerifier().getEncryptedVerifierHash(), equalTo(infoActual.getVerifier().getEncryptedVerifierHash()));
// now we use a newly generated salt/verifier and check
// if the file content is still the same
fs = new POIFSFileSystem();
infoActual = new EncryptionInfo(
fs, EncryptionMode.standard
, infoExpected.getVerifier().getCipherAlgorithm()
, infoExpected.getVerifier().getHashAlgorithm()
, infoExpected.getHeader().getKeySize()
, infoExpected.getHeader().getBlockSize()
, infoExpected.getVerifier().getChainingMode()
);
e = Encryptor.getInstance(infoActual);
e.confirmPassword(pass);
OutputStream os = e.getDataStream(fs);
IOUtils.copy(new ByteArrayInputStream(payloadExpected), os);
os.close();
bos.reset();
fs.writeFilesystem(bos);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
// FileOutputStream fos = new FileOutputStream("encrypted.docx");
// IOUtils.copy(bis, fos);
// fos.close();
// bis.reset();
nfs = new NPOIFSFileSystem(bis);
infoExpected = new EncryptionInfo(nfs);
d = Decryptor.getInstance(infoExpected);
passed = d.verifyPassword(pass);
assertTrue("Unable to process: document is encrypted", passed);
bos.reset();
is = d.getDataStream(nfs);
IOUtils.copy(is, bos);
is.close();
nfs.close();
byte payloadActual[] = bos.toByteArray();
assertThat(payloadExpected, equalTo(payloadActual));
}