准备数字证书
本文章描述了如何对word文档进行数签名的过程,代码经过实际验证可正常运行。
先准备好的数据证书
//生成根证书的密匙 openssl genrsa -out /root/ca/rootkey.pem 2048
//生成根证书 openssl req -x509 -new -key rootkey.pem -out rootcert.crt -subj /OU=zhui/O=zhai/L=zwang/ST=xa/C=sx/CN=www.whh.com
//生成客户端的密匙 openssl genrsa -out clientkey.pem 2048
//生成客户端证书的请求文件 openssl req -new -key clientkey.pem -out client.csr -subj /OU=chui/O=chai/L=cwang/ST=xa/C=sx/CN=www.whh.com
//用根证书来签发客户端证书 openssl x509 -req -in client.csr -CA rootcert.crt -CAkey rootkey.pem -CAcreateserial -days 3650 -out client.crt
//打包客户端资料为pkcs12格式 openssl pkcs12 -export -name xyz -in client.crt -inkey clientkey.pem -out client.pkcs12 -passout pass:changeit
签名代码
用于签名的类
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Collections;
import com.spire.doc.*;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
// field CN: 颁发给和颁发者
public class Test {
public static void spire() throws IOException {
// https://repo.e-iceblue.cn
// load Word
Document doc = new Document();
doc.loadFromFile("C:/tmp/abc.docx");
// add certificate
// version 4.5.1
doc.saveToFile("C:/tmp/abc_addsignature_1.docx", FileFormat.Docx_2013, "C:/tmp/cert/client.pkcs12", "changeit");
System.out.println("version 4.5.1 success");
// version 11.2.3
FileOutputStream out = new FileOutputStream("C:/tmp/abc_addsignature_2.docx");
doc.saveToStream(out, FileFormat.Docx_2013, "C:/tmp/cert/client.pkcs12", "changeit");
out.close();
System.out.println("version 11.2.3 success");
}
public static void poi() throws Exception {
// Signing an office document
/*
* loading the keystore - pkcs12 is used here, but of course jks & co are also
* valid the keystore needs to contain a private key and its certificate having
* a 'digitalSignature' key usage
*/
char password[] = "changeit".toCharArray();
File file = new File("C:/tmp/cert/client.pkcs12");
KeyStore keystore = KeyStore.getInstance("PKCS12");
FileInputStream fis = new FileInputStream(file);
keystore.load(fis, password);
fis.close();
// extracting private key and certificate
String alias = "xyz"; // alias of the keystore entry
Key key = keystore.getKey(alias, password);
X509Certificate x509 = (X509Certificate) keystore.getCertificate(alias);
/*
* filling the SignatureConfig entries (minimum fields, more options are
* available ...)
*/
SignatureConfig signatureConfig = new SignatureConfig();
signatureConfig.setKey((PrivateKey) key);
signatureConfig.setSignatureDescription("Custom description");
signatureConfig.setCommitmentType("Custom approved");
signatureConfig.setSigningCertificateChain(Collections.singletonList(x509));
OPCPackage pkg = OPCPackage.open("C:/tmp/456.docx", PackageAccess.READ_WRITE);
// signatureConfig.setOpcPackage(pkg);
// adding the signature document to the package
SignatureInfo si = new SignatureInfo();
si.setSignatureConfig(signatureConfig);
si.setOpcPackage(pkg);
si.confirmSignature();
// optionally verify the generated signature
boolean b = si.verifySignature();
// assert (b);
// optionally verify the generated signature
// for (SignaturePart sp : si.getSignatureParts()) {
// System.out.println("1-" + sp.validate());
// }
// System.out.println("2-" + si.verifySignature());
// write the changes back to disc
pkg.close();
System.out.println("poi success, " + b);
}
public static void main(String[] args) throws Exception {
Test.poi();
}
}
验证签名
部分代码用于验证签名是否正确
OPCPackage pkg = OPCPackage.open("C:/tmp/456.docx", PackageAccess.READ);
SignatureConfig sic = new SignatureConfig();
sic.setOpcPackage(pkg);
SignatureInfo si = new SignatureInfo();
si.setSignatureConfig(sic);
boolean isValid = si.validate();
依赖包
在pom.xml中增加依赖
<dependencies>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.doc</artifactId>
<version>11.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.santuario</groupId>
<artifactId>xmlsec</artifactId>
<version>2.0.4</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>com.e-iceblue</id>
<url>http://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
</repositories>