📄 cmsservlet.java
字号:
/** * j4sign - an open, multi-platform digital signature solution * Copyright (c) 2004 Roberto Resoli - Servizio Sistema Informativo - Comune di Trento. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * *//* * $Header: /cvsroot/j4sign/j4sign/src/java/core/it/trento/comune/j4sign/examples/CMSServlet.java,v 1.2 2005/03/10 18:09:12 resoli Exp $ * $Revision: 1.2 $ * $Date: 2005/03/10 18:09:12 $ */package it.trento.comune.j4sign.examples;import it.trento.comune.j4sign.cms.ExternalSignatureCMSSignedDataGenerator;import it.trento.comune.j4sign.cms.ExternalSignatureSignerInfoGenerator;import java.io.ByteArrayInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.PrintWriter;import java.io.StringWriter;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.PublicKey;import java.security.Security;import java.security.cert.CertStore;import java.security.cert.CertStoreException;import java.security.cert.CertificateException;import java.security.cert.CollectionCertStoreParameters;import java.util.ArrayList;import java.util.Hashtable;import java.util.Iterator;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.bouncycastle.asn1.ASN1Sequence;import org.bouncycastle.asn1.ASN1Set;import org.bouncycastle.asn1.DERInputStream;import org.bouncycastle.asn1.DERObjectIdentifier;import org.bouncycastle.asn1.DEROctetString;import org.bouncycastle.asn1.DERTags;import org.bouncycastle.asn1.cms.Attribute;import org.bouncycastle.asn1.cms.AttributeTable;import org.bouncycastle.asn1.cms.CMSAttributes;import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;import org.bouncycastle.asn1.util.ASN1Dump;import org.bouncycastle.asn1.x509.DigestInfo;import org.bouncycastle.asn1.x509.Time;import org.bouncycastle.cms.CMSException;import org.bouncycastle.cms.CMSProcessable;import org.bouncycastle.cms.CMSProcessableByteArray;import org.bouncycastle.cms.CMSSignedData;import org.bouncycastle.cms.CMSSignedDataGenerator;import org.bouncycastle.jce.provider.BouncyCastleProvider;/** * <code>CMSServlet</code> is the server side part of the j4sign usage example in a web environment.<br> * <code>CMSServlet</code> is a <code>HttpServlet</code> that takes care of generating and sending to the web client * the content to sign and the corresponding bytes to digest and encrypt. After receiving the signature and * the signer certificate, it encapsulates them, along with the signed content, in a CMS signed data message.<br> * <p> * The entire example, with the {@link it.trento.comune.j4sign.examples.SimpleSignApplet} counterpart, is * designed to permit the use of the standard JDK tools. * The applet can be executed with applet viewer tool (no HttpSession in the servlet, * nor HTML forms on the client side are used).<br> * <p> * N.B.: IN A REAL WORLD WEB APPLICATION SCENARIO, YOU CAN (AND SHOULD) TAKE ADVANTAGE OF THE FULL SERVLET API. * <p> * Here are the <code>CMSServlet</code> operations in detail: * <ol> * <li>Upon a GET request from the client specifiying a <code>retrieve</code> parameter with value <code>DATA</code>:<br> * Generates and sends as HTTP response, the message to sign (a simple text), base64 encoded; * </li> * <li>Upon a GET request from the client specifiying a <code>retrieve</code> parameter with value * <code>ENCODED_AUTHENTICATED_ATTRIBUTES</code>:<br> * Builds an {@link ExternalSignatureSignerInfoGenerator} object, using the message to sign, * and specifying MD5 with RSA encryption as signature algoritm;<br> * Uses this object to calculate <code>bytesToSign</code>, the bytes to digest and encrypt (ASN.1 Authenticated attributes);<br> * Stores the <code>ExternalSignatureSignerInfoGenerator</code>, and a textual dump of authenticates attributes,<br> * using the md5 digest of <code>bytesToSign</code> as a key.<br> * Sends the base64 encoding of <code>bytesToSign</code> as HTTP response.<br> * </li> * <li>Upon a GET request from the client specifiying a <code>retrieve</code> parameter with value <code>AUTHENTICATED_ATTRIBUTES_PRINTOUT</code> * and a <code>encodedHash</code> parameter with base64 encoded value:<br> * Retrieves using <code>encodedHash</code> as a key the textual dump of Authenticates attributes, and sends it as HTTP responses.<br> * </li> * <li>Upon a POST request from the client specifiying a <code>signature</code> parameter and a <code>certificate</code> parameter, * both with base64 encoded values:<br> * Decodes <code>signature</code> and <code>certificate</code>;<br> * Extracts from <code>certificate</code> the public key of the signer, and uses it to decrypt, using RSA algorithm, * the <code>signature</code>.<br> * Uses the decrypted value as a key to retrieve the <code>ExternalSignatureSignerInfoGenerator</code>. If such an object is found, the * signature is verified.<br> * The <code>ExternalSignatureSignerInfoGenerator</code>, completed with <code>signature</code> and <code>certificate</code> * informations, is passed to a {@link it.trento.comune.j4sign.cms.ExternalSignatureCMSSignedDataGenerator} for creating the CMS message.<br> * The CMS message is then stored on the server file system.<br> * Finally, a textual status message is returned as HTTP response. * </li> * @author Roberto Resoli */public class CMSServlet extends HttpServlet { /** * <code>DATA</code> is the sample data contet to be signed; it's a text shortly explaining what is going to happen. */ private final static String DATA = "This text has been retrieved from cmsservlet via http GET.\n" + "The applet has also retrived from the cmsservlet the so called 'authenticated attributes',\n" + "a set of data comprising:\n" + "\t- The md5 digest of this text.\n" + "\t- The ASN.1 ContentType of this text (pkcs7.data).\n" + "\t- A timestamp, taken from the server clock.\n" + "When you type the pin, and press return, the following will happen:\n" + "The 'authenticated attributes', hashed with md5, will be sent\n" + "to the Smart Card and there encrypted using your private key.\n" + "The certificate corresponding to the private key will also be extracted\n" + "from the Smart Card. The certificate and the encrypted hashing of\n" + "'authenticated attributes' are then sent to cmsservlet via http POST.\n" + "Finally, cmsservlet builds the CMS (PKCS7) object and saves it\n" + "on the server filesystem, if the signature is verified."; /** * Class encapsulating a SignerInfoGenerator-related informations to be stored after a signature request. * * @author Roberto Resoli */ private class SignerInfoGeneratorItem { private String attrPrintout = null; private ExternalSignatureSignerInfoGenerator sig = null; /** * Constructor. * * @param aSig the {@link ExternalSignatureSignerInfoGenerator} * @param aPrintOut the authenticated attributes textual dump at the time of the request. */ public SignerInfoGeneratorItem( ExternalSignatureSignerInfoGenerator aSig, String aPrintOut) { sig = aSig; attrPrintout = aPrintOut; } /** * The attributes printout getter. * * @return the authenticated attributes textual dump at the time of the request. */ public String getAttrPrintout() { return attrPrintout; } /** * The ExternalSignatureSignerInfoGenerator getter. * * @return the ExternalSignatureSignerInfoGenerator for encapsulating signer informations. */ public ExternalSignatureSignerInfoGenerator getSig() { return sig; } } /** * The repository for {@link SignerInfoGeneratorItem} objects. * Stores SignerInfoGenerator-related informations between HTTP requests. * */ private Hashtable signerInfoGeneratorTable = new Hashtable(); /** * Implementation of the GET method; returns informations to the client and stores * SignerInfoGenerator-related informations; see {@link CMSServlet} for details. * @see CMSServlet */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out .println("==================== DO GET METHOD START========================="); PrintWriter out = response.getWriter(); String retrieve = (String) request.getParameter("retrieve"); if (retrieve != null) { System.out.println("Retrieving: " + retrieve); if (retrieve.equals("DATA")) out.print(DATA); else if (retrieve.equals("ENCODED_AUTHENTICATED_ATTRIBUTES")) { ExternalSignatureSignerInfoGenerator gen = buildSignerInfoGenerator(); //s.setAttribute("signerInfo", infoGen); byte[] bytesToSign = getAuthenticatedAttributesBytes(gen); String attrPrintout = getAuthenticatedAttributesPrintout(bytesToSign); //calculate digest java.security.MessageDigest md5; try { md5 = java.security.MessageDigest.getInstance("MD5"); md5.update(bytesToSign); byte[] digest = md5.digest(); String storeKey = formatAsString(digest, ""); System.out.println("Saving SignerInfoGenerator with key: " + storeKey); System.out .println("The key is md5 digest of bytes to sign!");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -