这是CoSign SAPI的 Java 示例。它执行以下操作:
- 签署 pdf 文件,并在文件中放置临时签名
- 验证文件中的签名
- 对已有签名字段的 Word docx 文件进行签名
- 签署具有预先存在的签名字段的 PDF 文件
- 用户管理示例:列出所有用户的数字证书
例子:
import com.arx.sapiws.dss._1.*;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.cert.CertificateFactory;
import java.util.List;
import oasis.names.tc.dss._1_0.core.schema.DocumentType.Base64Data;
import oasis.names.tc.dss._1_0.core.schema.*;
import oasis.names.tc.saml._1_0.assertion.*;
public class CosignHelloWorld {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws Exception {
//read file name, signer name, signer password from command line
if (args.length < 3) {
System.out.println("Usage: java CosignHelloWorld <pdf-file> <signer-name> <signer-password>");
return;
}
String FileName = args[0];
String SignerName = args[1]; //cosign user
String SignerPassword = args[2]; //cosign user password
String FieldNameToSign = args[3];
String Reason = args[4];
if (!checkFile(FileName)) {
System.out.println("Cannot find '"+FileName+"' or it is read/write protected. Aborting.");
return;
}
// Sign DOCX document
SignDOCXExistField(FileName, FieldNameToSign, SignerName, SignerPassword);
// Sign PDF document
SignPDF(FileName, SignerName, SignerPassword);
// Sign an existing field in a PDF document
SignPDFExistField(FileName, FieldNameToSign, Reason, SignerName, SignerPassword);
// Verify all fields in a PDF document
List<SAPIFieldsInfo> fieldsInfo = VerifyFile(FileName, "application/pdf");
for (SAPIFieldsInfo fieldInfo : fieldsInfo)
{
String status = null;
if (!fieldInfo.getSignedFieldInfo().isIsSigned())
status = "Not Signed";
else
status = fieldInfo.getFieldStatus().getSignatureStatus() == 0 ? "Valid" : "Invalid";
System.out.println(fieldInfo.getSigFieldSettings().getName() + " : " + status);
}
// Get all user's certificates
List<byte[]> certs = ListUserCerts(SignerName, " ", SignerPassword);
for (byte[] certBytes : certs)
{
ByteArrayInputStream cert_value = new ByteArrayInputStream(certBytes);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
java.security.cert.X509Certificate X509Cert = (java.security.cert.X509Certificate) cf.generateCertificate(cert_value);
System.out.println("Issuer: " + X509Cert.getIssuerDN().getName());
}
}
private static byte[] getPDFBytes(String FileName) {
byte[] pdf;
// READ THE FILE INTO BUFFER
try
{
File F = new File(FileName);
if (!F.canRead())
{
return null;
}
if (!F.canWrite())
{
return null;
}
pdf = new byte[(int) F.length()];
FileInputStream FH = new FileInputStream(F);
FH.read(pdf, 0, (int) F.length());
FH.close();
}
catch (Exception e)
{
return null;
}
return pdf;
}
private static boolean checkFile(String fileName)
{
try
{
File F = new File(fileName);
if (!F.canRead())
{
return false;
}
if (!F.canWrite())
{
return false;
}
}
catch (Exception e)
{
return false;
}
return true;
}
private static void SignPDF(String FileName, String SignerName, String SignerPassword)
{
System.out.println("Trying to sign '" +FileName+ "' by '"+SignerName+ "' with password '"+SignerPassword+ "' ...");
byte[] fileBytes = getPDFBytes(FileName);
Base64Data corePDFBytes = new Base64Data();
corePDFBytes.setValue(fileBytes);
corePDFBytes.setMimeType("application/pdf");
DocumentType myDoc = new DocumentType();
myDoc.setBase64Data(corePDFBytes);
// set signer - USERNAME/DOMAIN
NameIdentifierType cosignUserProps = new NameIdentifierType();
cosignUserProps.setValue(SignerName); //User Name, try "John Miller"
cosignUserProps.setNameQualifier(" "); //Domain (relevant for Active Directory environment only)
// set signer - PASSWORD
CoSignAuthDataType cosignPassword = new CoSignAuthDataType();
cosignPassword.setLogonPassword(SignerPassword); //User Password, try "12345678"
// set signer - USERNAME+PASSWORD
RequestBaseType.OptionalInputs.ClaimedIdentity cosignUser = new RequestBaseType.OptionalInputs.ClaimedIdentity();
cosignUser.setName(cosignUserProps);
cosignUser.setSupportingInfo(cosignPassword);
//set signature field settings
SAPISigFieldSettingsType sigFieldSettings = new SAPISigFieldSettingsType();
sigFieldSettings.setName("SigField");
sigFieldSettings.setInvisible(Boolean.FALSE); //visible
sigFieldSettings.setX(366);
sigFieldSettings.setY(705);
sigFieldSettings.setWidth(182);
sigFieldSettings.setHeight(58);
sigFieldSettings.setDependencyMode(DependencyModeEnum.INDEPENDENT);
sigFieldSettings.setSignatureType(SignatureTypeEnum.DIGITAL);
sigFieldSettings.setEmptyFieldLabel("");
sigFieldSettings.setPage(1);
//initiate request components
RequestBaseType.InputDocuments inputs = new RequestBaseType.InputDocuments();
inputs.getDocumentHashOrOtherOrDocument().add(myDoc);
RequestBaseType.OptionalInputs optInputs = new RequestBaseType.OptionalInputs();
optInputs.setSignatureType("http://arx.com/SAPIWS/DSS/1.0/signature-field-create-sign");
optInputs.setClaimedIdentity(cosignUser);
optInputs.setSAPISigFieldSettings(sigFieldSettings);
optInputs.setReturnPDFTailOnly(Boolean.TRUE);
//initiate connection to COSign SAPI service
DSS service = new DSS();
DSSSoap port = service.getDSSSoap12();
//initiate request
SignRequest request = new SignRequest();
request.setOptionalInputs(optInputs);
request.setInputDocuments(inputs);
request.setRequestID("DummyRequestId");
//make the call
DssSignResult result = port.dssSign(request);
//CHECK RESULT:
ResponseBaseType.Result rc = result.getResult();
String errmsg = "" + rc.getResultMajor();
if (errmsg.compareTo("urn:oasis:names:tc:dss:1.0:resultmajor:Success") != 0) {
System.out.println("Cannot sign '"+FileName+"' got: "+rc.getResultMessage().getValue());
return;
}
System.out.println("Trying to append signature to '" +FileName+ "' ('"+SignerName+ "') ...");
// IF OK Get the signature:
DssSignResult.SignatureObject sig = result.getSignatureObject();
DssSignResult.SignatureObject.Base64Signature B64Sig = sig.getBase64Signature();
try
{
FileOutputStream FH = new FileOutputStream(FileName, true);
FH.write(B64Sig.getValue());
FH.close();
}
catch (Exception e)
{
System.out.println("Error writing to PDF file: " + e.getMessage());
return;
}
System.out.println("Signature of '" +SignerName+ "' appended to '"+FileName+ "'.");
}
/**
* Verifies a PDF, Word or Tiff file. The file is passed in as a byte array.
* @param FileBytes The file as byte array.
* @param FileType The type of the file as defined in ARX SAPI WS spec. Can accept the following values: application/pdf, application/msword, image/tiff
* @return The SAPIFieldsInfo structure that contains the details about all of the signatures present in the file.
*/
static public List<SAPIFieldsInfo> VerifyFile(String FileName, String FileType) throws Exception
{
System.out.println("Validating '" + FileName + "'");
DssVerifyResult result;
try {
byte[] fileBytes = getPDFBytes(FileName);
DSS service = new DSS();
DSSSoap port = service.getDSSSoap12();
RequestBaseType.InputDocuments inputDocs = new RequestBaseType.InputDocuments();
RequestBaseType.OptionalInputs optionalParams = new RequestBaseType.OptionalInputs();
// SET SIGNATURE TYPE (verify)
optionalParams.setSignatureType("http://arx.com/SAPIWS/DSS/1.0/signature-field-verify");
// SET FLAGS
optionalParams.setFlags(Long.valueOf(0));
Base64Data corePDFBytes = new Base64Data();
corePDFBytes.setValue(fileBytes);
corePDFBytes.setMimeType(FileType);
DocumentType myDoc = new DocumentType();
myDoc.setBase64Data(corePDFBytes);
inputDocs.getDocumentHashOrOtherOrDocument().add(myDoc);
// ALL DONE, MAKE A CALL:
VerifyRequest request = new VerifyRequest();
request.setOptionalInputs(optionalParams);
request.setInputDocuments(inputDocs);
request.setRequestID("DummyRequestId");
//make the call
result = port.dssVerify(request);
// CHECK RESULT:
ResponseBaseType.Result rc = result.getResult();
String errmsg = "" + rc.getResultMajor();
if (errmsg.compareTo("urn:oasis:names:tc:dss:1.0:resultmajor:Success") != 0) {
throw new Exception(rc.getResultMessage().getValue());
}
ResponseBaseType.OptionalOutputs outputs = result.getOptionalOutputs();
List<SAPIFieldsInfo> fieldInfos = outputs.getSAPIFieldsInfo();
if (fieldInfos == null) {
throw new Exception("File is not signed");
}
return fieldInfos;
}
catch (java.rmi.RemoteException e) {
throw e;
}
catch (Exception e) {
throw e;
}
}
private static void SignPDFExistField(String FileName, String FieldNameToSign, String Reason, String SignerName, String SignerPassword)
{
System.out.println("Trying to sign '" +FileName+ "' by '"+SignerName+ "' with password '"+SignerPassword+ "' ...");
byte[] fileBytes = getPDFBytes(FileName);
Base64Data corePDFBytes = new Base64Data();
corePDFBytes.setValue(fileBytes);
corePDFBytes.setMimeType("application/pdf");
DocumentType myDoc = new DocumentType();
myDoc.setBase64Data(corePDFBytes);
// set signer - USERNAME/DOMAIN
NameIdentifierType cosignUserProps = new NameIdentifierType();
cosignUserProps.setValue(SignerName); //User Name, try "John Miller"
cosignUserProps.setNameQualifier(" "); //Domain (relevant for Active Directory environment only)
// set signer - PASSWORD
CoSignAuthDataType cosignPassword = new CoSignAuthDataType();
cosignPassword.setLogonPassword(SignerPassword); //User Password, try "12345678"
// set signer - USERNAME+PASSWORD
RequestBaseType.OptionalInputs.ClaimedIdentity cosignUser = new RequestBaseType.OptionalInputs.ClaimedIdentity();
cosignUser.setName(cosignUserProps);
cosignUser.setSupportingInfo(cosignPassword);
//initiate request components
RequestBaseType.InputDocuments inputs = new RequestBaseType.InputDocuments();
inputs.getDocumentHashOrOtherOrDocument().add(myDoc);
RequestBaseType.OptionalInputs optInputs = new RequestBaseType.OptionalInputs();
optInputs.setSignatureType("http://arx.com/SAPIWS/DSS/1.0/signature-field-sign");
optInputs.setClaimedIdentity(cosignUser);
optInputs.setSignatureFieldName(FieldNameToSign);
optInputs.setReturnPDFTailOnly(Boolean.TRUE);
// SET THE REASON
if (Reason.compareTo("") != 0) {
ArrayOfConfValueType confValArray = new ArrayOfConfValueType();
ConfValueType confVal = new ConfValueType();
confVal.setConfValueID(ConfIDEnum.REASON);
confVal.setStringValue(Reason);
confValArray.getConfValue().add(confVal);
optInputs.setConfigurationValues(confValArray);
}
//initiate connection to COSign SAPI service
DSS service = new DSS();
DSSSoap port = service.getDSSSoap12();
//initiate request
SignRequest request = new SignRequest();
request.setOptionalInputs(optInputs);
request.setInputDocuments(inputs);
request.setRequestID("DummyRequestId");
//make the call
DssSignResult result = port.dssSign(request);
//CHECK RESULT:
ResponseBaseType.Result rc = result.getResult();
String errmsg = "" + rc.getResultMajor();
if (errmsg.compareTo("urn:oasis:names:tc:dss:1.0:resultmajor:Success") != 0) {
System.out.println("Cannot sign '"+FileName+"' got: "+rc.getResultMessage().getValue());
return;
}
System.out.println("Trying to append signature to '" +FileName+ "' ('"+SignerName+ "') ...");
// IF OK Get the signature:
DssSignResult.SignatureObject sig = result.getSignatureObject();
DssSignResult.SignatureObject.Base64Signature B64Sig = sig.getBase64Signature();
try
{
FileOutputStream FH = new FileOutputStream(FileName, true);
FH.write(B64Sig.getValue());
FH.close();
}
catch (Exception e)
{
System.out.println("Error writing to PDF file: " + e.getMessage());
return;
}
System.out.println("Signature of '" +SignerName+ "' appended to '"+FileName+ "'.");
}
private static List<byte[]> ListUserCerts(String User, String Domain, String Pass) throws Exception
{
System.out.println("Retrieving list of certificates for user: " + User);
DssSignResult result;
try {
//initiate connection to COSign SAPI service
DSS service = new DSS();
DSSSoap port = service.getDSSSoap12();
SignRequest request = new SignRequest();
RequestBaseType.OptionalInputs optInputs = new RequestBaseType.OptionalInputs();
// SET SIGNATURE TYPE (create field + sign)
optInputs.setSignatureType("http://arx.com/SAPIWS/DSS/1.0/enum-certificates");
// SET USERNAME / PASSWORD
RequestBaseType.OptionalInputs.ClaimedIdentity cosignUser = new RequestBaseType.OptionalInputs.ClaimedIdentity();
NameIdentifierType userName = new NameIdentifierType();
userName.setValue(User);
userName.setNameQualifier(Domain);
cosignUser.setName(userName);
CoSignAuthDataType userPass = new CoSignAuthDataType();
userPass.setLogonPassword(Pass);
cosignUser.setSupportingInfo(userPass);
optInputs.setClaimedIdentity(cosignUser);
// SET FLAGS
optInputs.setFlags(Long.valueOf(0));
// ALL DONE, MAKE A CALL:
request.setOptionalInputs(optInputs);
request.setInputDocuments(null);
result = port.dssSign(request);
// CHECK RESULT:
ResponseBaseType.Result rc = result.getResult();
String errmsg = "" + rc.getResultMajor();
if (errmsg.compareTo("urn:oasis:names:tc:dss:1.0:resultmajor:Success") == 0) {
return result.getOptionalOutputs().getAvailableCertificate();
}
else {
throw new Exception(rc.getResultMessage().toString());
}
}
catch (java.rmi.RemoteException e) {
throw e;
}
catch (Exception e) {
throw e;
}
}
private static void SignDOCXExistField(String FileName, String FieldNameToSign, String SignerName, String SignerPassword) throws MalformedURLException
{
System.out.println("Trying to sign '" +FileName+ "' by '"+SignerName+ "' with password '"+SignerPassword+ "' ...");
byte[] fileBytes = getPDFBytes(FileName);
Base64Data corePDFBytes = new Base64Data();
corePDFBytes.setValue(fileBytes);
corePDFBytes.setMimeType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
DocumentType myDoc = new DocumentType();
myDoc.setBase64Data(corePDFBytes);
// set signer - USERNAME/DOMAIN
NameIdentifierType cosignUserProps = new NameIdentifierType();
cosignUserProps.setValue(SignerName); //User Name, try "John Miller"
cosignUserProps.setNameQualifier(" "); //Domain (relevant for Active Directory environment only)
// set signer - PASSWORD
CoSignAuthDataType cosignPassword = new CoSignAuthDataType();
cosignPassword.setLogonPassword(SignerPassword); //User Password, try "12345678"
// set signer - USERNAME+PASSWORD
RequestBaseType.OptionalInputs.ClaimedIdentity cosignUser = new RequestBaseType.OptionalInputs.ClaimedIdentity();
cosignUser.setName(cosignUserProps);
cosignUser.setSupportingInfo(cosignPassword);
//initiate request components
RequestBaseType.InputDocuments inputs = new RequestBaseType.InputDocuments();
inputs.getDocumentHashOrOtherOrDocument().add(myDoc);
RequestBaseType.OptionalInputs optInputs = new RequestBaseType.OptionalInputs();
optInputs.setSignatureType("http://arx.com/SAPIWS/DSS/1.0/signature-field-sign");
optInputs.setClaimedIdentity(cosignUser);
//optInputs.setSignatureFieldName(FieldNameToSign);
//initiate connection to COSign SAPI service
DSS service = new DSS(new URL("https://prime.cosigntrial.com:8080/sapiws/dss.asmx"));
DSSSoap port = service.getDSSSoap12();
//initiate request
SignRequest request = new SignRequest();
request.setOptionalInputs(optInputs);
request.setInputDocuments(inputs);
//make the call
DssSignResult result = port.dssSign(request);
//CHECK RESULT:
ResponseBaseType.Result rc = result.getResult();
String errmsg = "" + rc.getResultMajor();
if (errmsg.compareTo("urn:oasis:names:tc:dss:1.0:resultmajor:Success") != 0) {
System.out.println("Cannot sign '"+FileName+"' got: "+rc.getResultMessage().getValue());
return;
}
System.out.println("Trying to append signature to '" +FileName+ "' ('"+SignerName+ "') ...");
// IF OK Get the signature:
ResponseBaseType.OptionalOutputs.DocumentWithSignature signedFile = result.getOptionalOutputs().getDocumentWithSignature();
byte[] newFileBytes = signedFile.getDocument().getBase64Data().getValue();
try
{
FileOutputStream FH = new FileOutputStream(FileName);
FH.write(newFileBytes);
FH.close();
}
catch (Exception e)
{
System.out.println("Error writing to PDF file: " + e.getMessage());
return;
}
System.out.println("The document was successfully signed");
}
}