Word DocX上的Java DecriptionInfo

时间:2017-07-21 13:05:53

标签: java apache-poi java-security

我把头发拉出来,因为我无法让样品上班 - 希望有人可以提供帮助.. 我想检测docx和doc文件是否受密码保护/加密。我已经看到这个发布在几个地方,但我不能让它工作 - 它不会抛出异常。有人能看出我做错了什么。注意我只需要检测密码..我不想打开文档。

        String fileLocation = "C:/myfile.docx";
        File file = new File(fileLocation);
        FileInputStream fis = new FileInputStream(file.getAbsolutePath());
        POIFSFileSystem pfis = new POIFSFileSystem(fis);

        try{
            EncryptionInfo info = new EncryptionInfo(pfis);
            EncryptionMode mode = info.getEncryptionMode();
            Decryptor d = Decryptor.getInstance(info);

            //Try and open it
            if(!d.verifyPassword(Decryptor.DEFAULT_PASSWORD))
            {
                //file is encrypted 
            }               
        }
        catch(GeneralSecurityException gse)
        {
            //file is encrypted
        }
        catch(EncryptedDocumentException edc)
        {
            //file is encrypted
        }

1 个答案:

答案 0 :(得分:1)

我没有详细说明让代码更小,但我只是采用了一个工厂类 - 比如SlideShowFactory - 并为H / XWPF修改了它。由于H / XWPF在文档级别上没有公共接口(截至目前),因此快速和简单的方法是返回一个Object。

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;

import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.poifs.crypt.Decryptor;
import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.DocumentFactoryHelper;
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

public class EncDetect {
    public static void main(String[] args) {
        String dir = "/home/kiwiwings/project/poi/poi/test-data";
        String[] files = {
            "document/bug53475-password-is-solrcell.docx",
            "document/password_tika_binaryrc4.doc",
            "document/58067.docx",
            "document/58804.doc"
        };

        for (String f : files) {
            try {
                DocumentFactory.create(new File(dir, f));
                System.out.println(f + " not encrypted");
            } catch (EncryptedDocumentException e) {
                System.out.println(f + " is encrypted");
            } catch (Exception e) {
                System.out.println(f + " " +e.getMessage());
            }
        }

    }

    static class DocumentFactory {
        public static Object create(NPOIFSFileSystem fs) throws IOException {
            return create(fs, null);
        }

        public static Object create(final NPOIFSFileSystem fs, String password) throws IOException {
            DirectoryNode root = fs.getRoot();

            // Encrypted OOXML files go inside OLE2 containers, is this one?
            if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) {
                InputStream stream = null;
                try {
                    stream = DocumentFactoryHelper.getDecryptedStream(fs, password);

                    return createXWPFDocument(stream);
                } finally {
                    IOUtils.closeQuietly(stream);
                }
            }

            // If we get here, it isn't an encrypted XWPF file
            // So, treat it as a regular HWPF one
            boolean passwordSet = false;
            if (password != null) {
                Biff8EncryptionKey.setCurrentUserPassword(password);
                passwordSet = true;
            }
            try {
                return createHWPFDocument(fs);
            } finally {
                if (passwordSet) {
                    Biff8EncryptionKey.setCurrentUserPassword(null);
                }
            }
        }

        public static Object create(InputStream inp) throws IOException, EncryptedDocumentException {
            return create(inp, null);
        }

        public static Object create(InputStream inp, String password) throws IOException, EncryptedDocumentException {
            // If clearly doesn't do mark/reset, wrap up
            if (! inp.markSupported()) {
                inp = new PushbackInputStream(inp, 8);
            }

            // Ensure that there is at least some data there
            byte[] header8 = IOUtils.peekFirst8Bytes(inp);

            // Try to create
            if (NPOIFSFileSystem.hasPOIFSHeader(header8)) {
                NPOIFSFileSystem fs = new NPOIFSFileSystem(inp);
                return create(fs, password);
            }
            if (DocumentFactoryHelper.hasOOXMLHeader(inp)) {
                return createXWPFDocument(inp);
            }
            throw new IllegalArgumentException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
        }

        public static Object create(File file) throws IOException, EncryptedDocumentException {
            return create(file, null);
        }

        public static Object create(File file, String password) throws IOException, EncryptedDocumentException {
            return create(file, password, false);
        }

        public static Object create(File file, String password, boolean readOnly) throws IOException, EncryptedDocumentException {
            if (!file.exists()) {
                throw new FileNotFoundException(file.toString());
            }

            NPOIFSFileSystem fs = null;
            try {
                fs = new NPOIFSFileSystem(file, readOnly);
                return create(fs, password);
            } catch(OfficeXmlFileException e) {
                IOUtils.closeQuietly(fs);
                return createXWPFDocument(file, readOnly);
            } catch(RuntimeException e) {
                IOUtils.closeQuietly(fs);
                throw e;
            }
        }

        protected static Object createHWPFDocument(NPOIFSFileSystem fs) throws IOException, EncryptedDocumentException {
            return new HWPFDocument(fs.getRoot());
        }

        protected static Object createXWPFDocument(InputStream stream) throws IOException, EncryptedDocumentException {
            return new XWPFDocument(stream);
        }

        protected static Object createXWPFDocument(File file, boolean readOnly) throws IOException, EncryptedDocumentException {
            try {
                OPCPackage pkg = OPCPackage.open(file, readOnly ? PackageAccess.READ : PackageAccess.READ_WRITE);
                return new XWPFDocument(pkg);
            } catch (InvalidFormatException e) {
                throw new IOException(e);
            }
        }
    }

}