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();
}
}
}
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 –
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