2015-11-24 1 views
-2

Comment pouvons-nous signer numériquement un document MS-Office binaire hérité (doc, xls, ppt) dans Apache POI, ou toute autre bibliothèque open source?Comment signer par programme un document MS Office binaire avec Java?

Les formats Open XML sont couverts à How to programatically sign an MS office XML document with Java?

+4

downvoted par manque d'effort de recherche: avez-vous essayé de chercher "apache poi sign numériquement" dans un moteur de recherche de votre choix? Il y a eu beaucoup d'exemples pour moi, par exemple https://poi.apache.org/apidocs/org/apache/poi/poifs/crypt/dsig/SignatureInfo.html –

+0

J'ai vu ces exemples et les ai essayés, mais ils ne fonctionnaient que pour les fichiers de type .docx, .pptx . xlsx (fichiers basés sur xml). – Hbh

Répondre

1

j'ai pu signer fichier .doc en créant la signature XML détaché, puis en ajoutant sous le répertoire racine à l'aide POIFSFileSystem, exemple ci-dessous:

public class OfficeDocumentSigner2 { 


    public static void main(String[] args) { 
     signClassicOfficeDocuments(); 
    } 

    private static String sign() { 

     // First, create a DOM XMLSignatureFactory that will be used to 
     // generate the XMLSignature and marshal it to DOM. 
     XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM"); 
     OutputStream os = null; 
     String signedDoc = "C:\\Users\\Desktop\\digitalSign\\signdoc_signed.xml"; 
     try { 
      // Create a Reference to an external URI that will be digested 
      // using the SHA1 digest algorithm 

      Reference ref = fac.newReference(officeFilePath, fac.newDigestMethod(DigestMethod.SHA1, null)); 
      // Create the SignedInfo 
      SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS, (C14NMethodParameterSpec) null), fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), 
        Collections.singletonList(ref)); 

      // Create the Document that will hold the resulting XMLSignature --> detached 
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
      dbf.setNamespaceAware(true); // must be set 
      Document doc = dbf.newDocumentBuilder().newDocument(); 

      // certificate info 
      File file = new File("C:\\Users\\Desktop\\digitalSign\\test101\\KeyStore.jks"); 
      // extracting private key and certificate 
      String alias = "certAlias"; 
      X509Certificate x509 = null; 
      // loading the keystore 
      KeyStore keystore = KeyStore.getInstance("JKS"); 
      FileInputStream fis = new FileInputStream(file); 
      keystore.load(fis, password); 
      fis.close(); 
      x509 = (X509Certificate) keystore.getCertificate(alias); 
      KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) keystore.getEntry(alias, new KeyStore.PasswordProtection(password)); 

      // Create the KeyInfo containing the X509Data. 
      // ref : http://www.oracle.com/technetwork/articles/javase/dig-signature-api-140772.html 
      KeyInfoFactory kif = fac.getKeyInfoFactory(); 
      List x509Content = new ArrayList(); 
      x509Content.add(x509.getSubjectX500Principal().getName()); 
      x509Content.add(x509); 
      X509Data xd = kif.newX509Data(x509Content); 
      KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd)); 

      // Create a DOMSignContext and specify the DSA PrivateKey and 
      // location of the resulting XMLSignature's parent element 
      DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc); 
      dsc.setBaseURI(baseURI); 
      // Create the XMLSignature (but don't sign it yet) 
      XMLSignature signature = fac.newXMLSignature(si, ki); 

      // Marshal, generate (and sign) the enveloped signature 
      signature.sign(dsc); 

      // Output the resulting document. 

      os = new FileOutputStream(signedDoc); 
      TransformerFactory tf = TransformerFactory.newInstance(); 
      Transformer trans = tf.newTransformer(); 
      trans.transform(new DOMSource(doc), new StreamResult(os)); 


     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return signedDoc; 
    } 

    public static void signClassicOfficeDocuments() { 

     InputStream is; 
     try { 
      //sign document 
      String signaturePath = sign(); 
      InputStream signatureAsIS = new FileInputStream(signaturePath); 

      is = new FileInputStream(fileName); 
      POIFSFileSystem poifs = new POIFSFileSystem(is); 
      DirectoryEntry dirEntry = poifs.createDirectory("_xmlsignatures"); // create a new DirectoryEntry in the root directory 
      dirEntry.createDocument("9149", signatureAsIS); 

      String destPath = "C://Users//Desktop//digitalSign//test_11_24_signedByMe.doc"; 
      OutputStream os = new FileOutputStream(destPath); 
      poifs.writeFilesystem(os); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 


}