在服务器客户端条件下使用USB驱动程序生成PDF [英] Sigining a PDF using USB driver in server client condition

查看:131
本文介绍了在服务器客户端条件下使用USB驱动程序生成PDF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个项目,我需要使用基于usb的数字签名来签署pdf。我在本地尝试了以下代码并能够签署pdf。我的问题是天气,以下代码将在基于senerio的客户端服务器中运行。

I am doing a project where i need to sign a pdf using a usb based digital signature. I have tried the following code locally and able to sign the pdf. my problem is weather the following code will work in a client server based senerio.

我的代码是:

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfSignatureAppearance;
import com.lowagie.text.pdf.PdfStamper;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.security.cert.CRL;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import javax.servlet.RequestDispatcher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import sun.security.mscapi.SunMSCAPI;

public class Testing {
    private static boolean resFlag;

    public static void main (String args[])
    {
     try {

        BouncyCastleProvider providerBC = new BouncyCastleProvider();
        Security.addProvider(providerBC);
        SunMSCAPI providerMSCAPI = new SunMSCAPI();
        Security.addProvider(providerMSCAPI);
        KeyStore ks = KeyStore.getInstance("Windows-MY");
        ks.load(null, null);
        String alias = (String)ks.aliases().nextElement();
        PrivateKey pk = (PrivateKey)ks.getKey(alias, null);
        Certificate[] chain = ks.getCertificateChain(alias);


//         //String e = request.getParameter("digiFile");
//         KeyStore ks = KeyStore.getInstance("pkcs12");
//         String f10 = CommonUtil.getRealPath();
//         String str8 = f10 + "/DigiFiles/";
//         //System.out.println("str8-->>>>>>>>" + str8 + e);
//          ks.load(new FileInputStream("F:/DigiFiles/Anurag Goel.pfx"), "123".toCharArray());
//
//
//         System.out.println("The actual path is " + str8);
//         String alias = (String)ks.aliases().nextElement();
//         PrivateKey key = (PrivateKey)ks.getKey(alias, "123".toCharArray());
//         Certificate[] chain = ks.getCertificateChain(alias);
         PdfReader reader = new PdfReader("F:/test.pdf");
         FileOutputStream os = new FileOutputStream("F:/SampleOutPut61.pdf");
         PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0',null,true);
         PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
         appearance.setCrypto(pk, chain, (CRL[])null, PdfSignatureAppearance.VERISIGN_SIGNED);
         appearance.setReason("elicense project");
         appearance.setLocation("Assam");
         appearance.setVisibleSignature("hi");
         stamper.close();
      } catch (KeyStoreException var27) {
         var27.printStackTrace();
         resFlag = false;
      } catch (NoSuchAlgorithmException var28) {
         var28.printStackTrace();
         resFlag = false;
      } catch (CertificateException var29) {
         var29.printStackTrace();
         resFlag = false;
      } catch (FileNotFoundException var30) {
         var30.printStackTrace();
         resFlag = false;
      } catch (IOException var31) {
         var31.printStackTrace();
         resFlag = false;
      } catch (UnrecoverableKeyException var32) {
         var32.printStackTrace();
         resFlag = false;
      } catch (DocumentException var33) {
         var33.printStackTrace();
         resFlag = false;
      } catch (Exception var34) {
         var34.printStackTrace();
         resFlag = false;
      } finally {
         RequestDispatcher rd;


      }

   }
}

请给我一些建议。谢谢所有

Please give me suggestion . thanks all

推荐答案


  1. 您使用的是错误的iText版本,因此您创建的签名不是未来证明(请阅读本书,找出问题所在您的代码)。

  2. 您取决于操作系统是Windows的事实。您的服务器也是Windows服务器吗?如果它是Linux服务器,您的代码将无法运行。请咨询您的托管服务提供商,并询问您的托管服务提供商是否允许您在该服务器上安装USB令牌(如果它不是专用服务器,他们可能会拒绝该服务器)。

  3. 您正在使用Windows-MY,这意味着您将身份验证委派给操作系统。如果USB需要密码(他们通常会这样做),Windows将打开一个对话框供您填写该密码。如果您在服务器上部署它:每次有人请求签名时,您是否会有人坐在该服务器旁边填写该密码?

  4. USB令牌是专为人们签署文件而设计的手动。他们通常有特定的限制。例如:通常,您每秒不能应用超过1个签名。这在网络环境中通常是不够的。在Web环境中,您需要在服务器上使用安装硬件安全模块(HSM)。

  1. You are using the wrong iText version, hence you are creating signatures that are not future proof (please read this book to find out what's wrong with your code).
  2. You are depending on the fact that the operating system is Windows. Is your server also a Windows server? Your code won't work if it's a Linux server. Check with your hosting provider and also ask your hosting provider if it is allowed for you to have a USB token on that server (if it's not a dedicated server, chances are they are going to refuse that).
  3. You are using Windows-MY which means that you delegate the authentication to the operating system. If the USB needs a passphrase (they usually do), Windows will open up a dialog box for you to fill out that passphrase. If you deploy this on a server: will you have somebody sitting next to that server to fill out that password every time somebody requests a signature?
  4. USB tokens are designed for people to sign a document manually. They usually have specific limitations. For instance: normally, you can not apply more than 1 signature per second. This is usually insufficient in a web context. In a web context, you are expected to use install a Hardware Security Module (HSM) on your server.

虽然您的代码可能正常工作理论上,在服务器上,我看到很多原因,为什么使用在客户端/服务器环境中的独立机器上运行的代码不是明智的决定。有太多实际问题(例如身份验证,速度,iText的错误版本......)可能会导致您的项目出错。我会回答你的问题是否,该代码是否适用于客户端/服务器场景。

While your code may work on a server in theory, I see a lot of reasons why it's not a wise decision to use the code that works on a standalone machine in a client/server environment. There are too many practical issues (such as authentication, speed, wrong version of iText,...) that can make your project go wrong. I would answer "no" to your question whether that code will work in a client/server scenario.

更新:

在您对我的回答的评论中,您指出您的服务器是Linux服务器。很明显,使用Windows-MY永远不会在Linux服务器上运行。您必须使用PKCS#11而不是Windows-MY来与存储令牌的硬件设备进行通信。这是一个代码示例,适用于SafeNet的Luna SA。如您所见,它使用PKCS#11:

In your comments to my answer, you indicate that your server is a Linux server. It should be obvious that using "Windows-MY" will never work on a Linux server. You'll have to use PKCS#11 instead of Windows-MY to talk to the hardware device on which your token is stored. This is a code sample that works on a Luna SA from SafeNet. As you can see, it uses PKCS#11:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Properties;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import sun.security.pkcs11.SunPKCS11;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.log.SysoLogger;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.security.BouncyCastleDigest;
import com.itextpdf.text.pdf.security.CertificateUtil;
import com.itextpdf.text.pdf.security.CrlClient;
import com.itextpdf.text.pdf.security.CrlClientOnline;
import com.itextpdf.text.pdf.security.DigestAlgorithms;
import com.itextpdf.text.pdf.security.ExternalDigest;
import com.itextpdf.text.pdf.security.ExternalSignature;
import com.itextpdf.text.pdf.security.MakeSignature;
import com.itextpdf.text.pdf.security.OcspClient;
import com.itextpdf.text.pdf.security.OcspClientBouncyCastle;
import com.itextpdf.text.pdf.security.PrivateKeySignature;
import com.itextpdf.text.pdf.security.TSAClient;
import com.itextpdf.text.pdf.security.TSAClientBouncyCastle;
import com.itextpdf.text.pdf.security.MakeSignature.CryptoStandard;

public class C4_01_SignWithPKCS11HSM {

    public static final String SRC = "/home/itext/hello.pdf";
    public static final String PROPS = "/home/itext/key.properties";
    public static final String DEST = "/home/itext/hello_hsm.pdf";

    public void sign(String src, String dest,
            Certificate[] chain, PrivateKey pk,
            String digestAlgorithm, String provider, CryptoStandard subfilter,
            String reason, String location,
            Collection<CrlClient> crlList,
            OcspClient ocspClient,
            TSAClient tsaClient,
            int estimatedSize)
                    throws GeneralSecurityException, IOException, DocumentException {
        // Creating the reader and the stamper
        PdfReader reader = new PdfReader(src);
        FileOutputStream os = new FileOutputStream(dest);
        PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
        // Creating the appearance
        PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
        appearance.setReason(reason);
        appearance.setLocation(location);
        appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
        // Creating the signature
        ExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm, provider);
        ExternalDigest digest = new BouncyCastleDigest();
        MakeSignature.signDetached(appearance, digest, pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);
    }

    public static void main(String[] args) throws IOException, GeneralSecurityException, DocumentException {

        LoggerFactory.getInstance().setLogger(new SysoLogger());

        Properties properties = new Properties();
        properties.load(new FileInputStream(PROPS));
        char[] pass = properties.getProperty("PASSWORD").toCharArray();
        String pkcs11cfg = properties.getProperty("PKCS11CFG");

        BouncyCastleProvider providerBC = new BouncyCastleProvider();
        Security.addProvider(providerBC);
        FileInputStream fis = new FileInputStream(pkcs11cfg);
        Provider providerPKCS11 = new SunPKCS11(fis);
        Security.addProvider(providerPKCS11);

        KeyStore ks = KeyStore.getInstance("PKCS11");
        ks.load(null, pass);
        String alias = (String)ks.aliases().nextElement();
        PrivateKey pk = (PrivateKey)ks.getKey(alias, pass);
        Certificate[] chain = ks.getCertificateChain(alias);
        OcspClient ocspClient = new OcspClientBouncyCastle();
        TSAClient tsaClient = null;
        for (int i = 0; i < chain.length; i++) {
            X509Certificate cert = (X509Certificate)chain[i];
            String tsaUrl = CertificateUtil.getTSAURL(cert);
            if (tsaUrl != null) {
                tsaClient = new TSAClientBouncyCastle(tsaUrl);
                break;
            }
        }
        List<CrlClient> crlList = new ArrayList<CrlClient>();
        crlList.add(new CrlClientOnline(chain));
        C4_01_SignWithPKCS11HSM app = new C4_01_SignWithPKCS11HSM();
        app.sign(SRC, DEST, chain, pk, DigestAlgorithms.SHA256, providerPKCS11.getName(), CryptoStandard.CMS,
                "HSM test", "Ghent", crlList, ocspClient, tsaClient, 0);
    }
}

使用的配置文件的内容看起来像这个:

The content of the config file that is used looks like this:

Name = Luna
library = /usr/lunasa/lib/libCryptoki2_64.so
slot = 1

请注意所以可能是在您的案例的另一个目录中,您的证书可能在另一个插槽中。我还使用属性文件来存储证书的密码。显然我不会分享我的密码; - )

Note that the so may be in another directory in your case, and your certificate may be in another slot. I also use a properties file to store the password for the certificate. Obviously I won't share my password ;-)

这个例子是在GlobalSign拥有的服务器上使用GlobalSign证书进行测试的。

This example was tested on a server owned by GlobalSign using a GlobalSign certificate.

这篇关于在服务器客户端条件下使用USB驱动程序生成PDF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆