⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simplesignapplet.java

📁 java 实现的签名方案
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/** *	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/SimpleSignApplet.java,v 1.4 2005/03/06 18:06:47 resoli Exp $ * $Revision: 1.4 $ * $Date: 2005/03/06 18:06:47 $ */package it.trento.comune.j4sign.examples;import iaik.pkcs.pkcs11.TokenException;import iaik.pkcs.pkcs11.wrapper.PKCS11Constants;import iaik.pkcs.pkcs11.wrapper.PKCS11Exception;import it.trento.comune.j4sign.pcsc.CardInfo;import it.trento.comune.j4sign.pcsc.PCSCHelper;import it.trento.comune.j4sign.pkcs11.PKCS11Signer;import java.awt.*;import javax.swing.*;import java.io.*;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;import java.net.URLEncoder;import java.security.cert.CertificateException;import java.util.List;/** * This is the client side part of the j4sign usage example in a web environment.<br> * <code>SimpleSignApplet</code> is <i>simple</i> in the sense that raffinate GUI features  * are avoided (like multiple threads used to correctly implement the progress bar), in favor * to a clear exposition of specific signature procedures. * <p> * The goal was to illustrate an approach in which the client side digesting - encryption, involving  * cryptographic token management via JNI, is completely separated from server side CMS message building. * This lightens the applet, which has not to bear the wheight of the BouncyCastle classes. * <p> * Another feature is the encapsulation of the JNI part (the excellent pkcs11 wrapper  developed  * by IAIK of Graz University of Technology, and the pcsc wrapper taken from Open Card Framework project), *  along with the corresponding native libraries, in a standard Java Extension, named <code>SmartCardAccess</code>.  * See {@link it.trento.comune.j4sign.installer} and <a href="http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/extensions.html"> * Deploying Java Extensions<a>.<br> * The extension is deployed automatically the first time the applet is loaded.<br> * The ultimate dependency for the applet is the cryptoki library, which has to be provided from the * PKCS11 token manufacturer. The {@link it.trento.comune.j4sign.pcsc.PCSCHelper} class uses the pcsc wrapper  * trying to infer the correct library from the ATR string returned from the token. * <p> * Some words about security; all downloaded jars, including the <code>SmartCardAccess</code> extension, * has to be signed in order to work; this is needed for tho reasons:<ul><li>the applet loads native libraries</li> * <li>the applet deploys a java extension.</li></ul> This gives more confidence about signing software integrity. * <p> * The entire example, with the {@link it.trento.comune.j4sign.examples.CMSServlet} server side 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> * This eases the use of an IDE for test and debugging; we use, and recommend, the <a href="http://www.eclipse.org">Eclipse</a>) IDE. * <p> * N.B.: IN A REAL WORLD WEB APPLICATION SCENARIO, YOU CAN (AND SHOULD) TAKE ADVANTAGE OF THE FULL SERVLET API, AND HTTP/HTML FEATURES. * <p> *  * Here are the <code>SimpleSignApplet</code> operations in detail; the applet talks with the server (servlet) in HTTP: * <ol> * <li>The applet initialization method (init()) builds the GUI layout: a text area in the center, and, in the bottom, * a button to load data from server and a password field.<br> * A detailed log is shown on System out (Java Plugin console). * </li> * <li>When the "Load data" button is pressed, a GET request is generated, specifiying a <code>retrieve</code> parameter with value  * <code>DATA</code>; the server returns the message to sign.<br>Immediately after, another GET request is sent, specifiying a  * <code>retrieve</code> parameter with value <code>ENCODED_AUTHENTICATED_ATTRIBUTES</code>; the server calculates and  * returns the data to digest and encrypt (authenticated attributes).<br> * The message and a textual representation of the authenticated attributes are presented in the text area.<br> * Note that authenticated attributes includes a timestamp, then even if the message is the same, the bytes to * digest and encrypt change every time the user loads the data from server. * </li> * <li>When the user insert the password in the field and press return, the signing process starts:<br> * <ol type="a"><li>the PCSC layer is invoked to query for an inserted token, and if one is found the relative  * PKCS#11 cryptoki is (hopefully) detected and loaded. *</li> *<li>Then the token is checked for the required signature algorithm (RSA_PKCS), and queried for a suitable certificate - private key pair. *</li> **<li>Then MD5 digest of authenticated attributes is calculated in software and the result sent to the token *for the encryption procedure. *</li> *</ol> * <li>The signature is sent to the server via HTTP POST, along with the signer certificate extracted from the token. * </li> * <li> * The server acknowledges confirming signature verification and CMS building and saving. * </li> * </ol> * <p><b>N.B. note that in this example signature verification only ensures integrity; a complete verification * to ensure non-repudiation requires checking the full certification path including the * CA root certificate, and CRL verification on the CA side. (Good stuff  for a next release ...)</b> *  *  * @see it.trento.comune.j4sign.examples.CMSServlet * @author Roberto Resoli */public class SimpleSignApplet extends JApplet implements        java.awt.event.ActionListener {    private JTextArea dataArea = null;    private JButton loadButton = new JButton("Load Data");    private JPasswordField pwd = new JPasswordField();    private java.io.PrintStream log = null;    private JProgressBar progressBar = null;    private String textToSign = null;    private String attrPrintout = null;    private byte[] bytesToSign = null;    private byte[] digest = null;    private byte[] encryptedDigest = null;    private java.lang.String cryptokiLib = null;    private java.lang.String signerLabel = null;        private java.lang.String baseHttpUrl = null;    private byte[] certificate = null;    private static final short SEARCH_BY_PRIVATE_KEY = 0;    private static final short SEARCH_BY_CERTIFICATE_KEY_USAGE = 1;    private short OBJECT_SEARCH_CRITERION = SEARCH_BY_CERTIFICATE_KEY_USAGE;    public static final int ERROR = -1;    public static final int RESET = 0;    public static final int DATA_LOADED = 1;    public static final int SIGN_DONE = 2;        public static final int POST_ERROR = -1;    public static final int POST_OK_VERIFY_OK = 0;    public static final int POST_OK_VERIFY_ERROR = 1;    public static final String DEFAULT_BASE_HTTP_URL = "http://localhost:8080/sc/cmsservlet";    /**      * The implementation of the callback method for ActionListener.     * Entry point for all applet operations: data loading, signature, data sending.     *      * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)     */    public void actionPerformed(java.awt.event.ActionEvent e) {        try {            if (e.getSource() == this.loadButton) {                if(loadData()){                    this.pwd.setEnabled(true);                    this.loadButton.setEnabled(false);                    setStatus(DATA_LOADED,                        	"Read carefully the text above. Type pin and press RETURN to sign.");                }else                    setStatus(ERROR, "Cannot Load data from server");            }            if (e.getSource() == this.pwd) {                if (detectCardAndCriptoki()) {                    log                            .println("\n============= PKCS11 SIGNATURE START =============\n");                    sign();                    log                            .println("\n=============  PKCS11 SIGNATURE END  =============\n");                                        int rc = sendSignatureAndCertificate();                    switch (rc) {                    case POST_ERROR:                        setStatus(SIGN_DONE, "Signature done - error sending data to server.");                        break;                    case POST_OK_VERIFY_OK:                        setStatus(SIGN_DONE, "Signature done - data sent to server and verified.");                        break;                    case POST_OK_VERIFY_ERROR:                        setStatus(SIGN_DONE, "Signature done - data sent to server but NOT verified!");                        break;                    default:                        break;                    }                                                            pwd.setEnabled(false);                    this.loadButton.setEnabled(true);                } else                    setStatus(ERROR,                            "No token or no suitable objects on token.");            }        } catch (Exception ex) {            log.println(ex.toString());            setStatus(ERROR, ex.toString());        } finally {            pwd.setText("");        }    }    /**     * Cleans up whatever resources are being held. If the applet is active it     * is stopped.     * Forces a system garbage collection to reclaim memory.     *      * @see #init     * @see #start     * @see #stop     */    public void destroy() {        super.destroy();        log.println("Destroying applet and garbage collecting...");        //task = null;        System.gc();        log.println("Garbage collection done.");        // insert code to release resources here    }    /**     * Gets the signer certificate.     *      * @return byte the certificate bytes as extracted from the pkcs11 token.     */    public byte[] getCertificate() {        return certificate;    }    /**     * Gets the native cryptoki library name; this is the library     * provided by the token manufacturer that implements the PKCS#11 standard API.     *      * @return java.lang.String     */    private java.lang.String getCryptokiLib() {        return cryptokiLib;    }    /**     * Returns the digest of the bytes to sign.     *      * @return byte[] data to be sento to the token for encryption.     */    public byte[] getDigest() {        return digest;    }    /**     * The result of encryption of data obtained from  {@link #getDigest()}; Encryption     * is done on the token.     *      * @return iaik.pkcs.pkcs7.SignedData     */    public byte[] getEncryptedDigest() {        return encryptedDigest;    }    /**     * The textual identifier of the objects related to the signer     * on a PKCS#11 token; do not rely only on this to find objects;     * labels are manufacturer dependent.      *      * @return java.lang.String     */    private java.lang.String getSignerLabel() {        return signerLabel;    }    /**     * Triggers three different HTTP GET requests against the server:     * <ol>     * <li>The first for retrieving the textual content to sign (the message)</li>     * <li>The second for retrieving the time-dependent     *  bytes to sign (the authenticated attributes)</li>     * <li>The third for retrieving a textual rapresentetion of the bytes to sign      * (the authenticated attributes printout)</li>     * </ol>     *      * The local digest value is updated according with the new bytes to sign.     *      * @return true if all data retrieval operations were successful.     */    private boolean loadData() {        boolean dataLoaded = false;                log.println("Retrieving data from server...");        this.textToSign = retrieveTextToSign();        this.bytesToSign = retrieveBytesToSign();        if ((this.textToSign != null) && (this.bytesToSign != null)) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -