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

📄 signcert.java

📁 用于移动设备上的java虚拟机源代码
💻 JAVA
字号:
/* * @(#)SignCert.java	1.3 02/07/25 @(#) * * Copyright (c) 2000-2002 Sun Microsystems, Inc.  All rights reserved. * PROPRIETARY/CONFIDENTIAL * Use is subject to license terms. */package com.sun.midp.jadtool;import java.io.*;import java.util.Date;import java.security.KeyStore;import java.security.NoSuchAlgorithmException;import java.security.KeyStoreException;import java.security.Key;import java.security.PrivateKey;import java.security.SignatureException;import java.security.InvalidKeyException;import java.security.NoSuchProviderException;import java.security.UnrecoverableKeyException;import java.security.cert.Certificate;import java.security.cert.X509Certificate;import java.security.cert.CertificateException;import com.sun.midp.jadtool.AppDescriptorException;// FIX: Use of these classes is not portable.  (See below.)//      Perhaps they should be re-implemented at some point.import sun.security.x509.AlgorithmId;import sun.security.x509.X509CertImpl;import sun.security.x509.X509CertInfo;import sun.security.x509.X500Name;import sun.security.x509.CertificateSubjectName;import sun.security.x509.CertificateIssuerName;import sun.security.x509.CertificateValidity;import sun.security.x509.CertificateSerialNumber;import sun.security.x509.CertificateAlgorithmId;/** * SignCert is a utility class used by the AppDescriptor Class to * modify a self-signed certificate in a KeyStore.  These methods * do not modify an AppDescriptor at all, but only modify the contents * of a Java KeyStore.   * <p> * * Given the alias of a self-signed certificate and the alias of  * a "signing" certificate...the alias of another certificate that  * is paired with a private key...the static method  * <code>SignACert</code> will replace the self-signed certificate * with the same certificate signed by the owner of the "signing" * certificate. * <p> * * PORTABILITY WARNING! * -------------------- * This class uses Sun implementation specific classes in the * <code>sun.security.x509.*</code> namespace imported here.  This * is NOT portable to Java runtime environments provided by other * vendors.  It may not even be supported in future releases * of the Sun JDK.  This code works under Sun's JDK1.3.     * <p> * * We were forced to use Sun's X509 certificate implementation classes  * directly because the public X509 certificate methods in * <code>java.security.cert.*</code> do not provide ways to  * programatically modify fields within a X509 certificate object. * <p> * * For more information about the sun.* classes, see:<br> * <a href=http://java.sun.com/products/jdk/faq/faq-sun-packages.html> * http://java.sun.com/products/jdk/faq/faq-sun-packages.html</a> */public class SignCert {    /**     * Signs a certificate <code>signee_alias</code> using the signing      * (private) key associated with <code>signing_alias</code>.       * <code>keyPass</code> unlocks the signing key.     * <p>     * Creates a signed certificate and stores it as a single-element      * certificate chain associated with <code>signee_alias</code>.     */        public static void signACert(String signee_alias, String signing_alias,                                  char[] keyPass, KeyStore keyStore,                                  char[] storePass)        throws AppDescriptorException, CertificateException, IOException,               KeyStoreException, NoSuchAlgorithmException,                InvalidKeyException, UnrecoverableKeyException,               NoSuchProviderException, SignatureException, Exception {        String sigAlgName;        if (signee_alias == null || signing_alias == null ||             keyPass == null || keyStore == null) {            throw new AppDescriptorException("signACert got a null argument",                                             4);        }                Object[] objs = recoverPrivateKey(signing_alias, storePass,                                           keyPass, keyStore);        PrivateKey privKey = (PrivateKey)objs[0];        if (keyPass == null)            keyPass = (char[])objs[1];                // Determine the signature algorithm        // If no signature algorithm was specified at the command line,        // we choose one that is compatible with the selected private key        String keyAlgName = privKey.getAlgorithm();        if (keyAlgName.equalsIgnoreCase("DSA")            || keyAlgName.equalsIgnoreCase("DSS")) {            sigAlgName = "SHA1WithDSA";        } else if (keyAlgName.equalsIgnoreCase("RSA")) {            sigAlgName = "SHA1WithRSA";        } else {            throw new                AppDescriptorException("Cannot derive signature algorithm", 5);        }        // Get the old certificate        Certificate oldCert = keyStore.getCertificate(signee_alias);        if (oldCert == null) {            throw new                AppDescriptorException(signee_alias + " has no public key", 4);        }        if (!(oldCert instanceof X509Certificate)) {            throw new AppDescriptorException(signee_alias +                " has no X.509 certificate", 6);        }                // Get the "signing" certificate        Certificate signingCert = keyStore.getCertificate(signing_alias);        if (signingCert == null) {            throw new                AppDescriptorException(signee_alias + " has no public key", 7);        }        if (!(signingCert instanceof X509Certificate)) {            throw new AppDescriptorException(signee_alias +                " has no X.509 certificate", 8);        }               // convert to X509CertImpl, so that we can modify selected fields        // (no public APIs available yet)        byte[] encoded = oldCert.getEncoded();        X509CertImpl certImpl = new X509CertImpl(encoded);        X509CertInfo certInfo = (X509CertInfo)certImpl.get(X509CertImpl.NAME +                                "." + X509CertImpl.INFO);                       // get an X509Certificate from the signing_alias        encoded = signingCert.getEncoded();        X509CertImpl signingCertImpl = new X509CertImpl(encoded);        X509CertInfo signingCertInfo = (X509CertInfo)             signingCertImpl.get(X509CertImpl.NAME                                + "." + X509CertImpl.INFO);                     // Extend its validity        int validity = 180;  // 180 days default        Date firstDate = new Date();        Date lastDate = new Date();        lastDate.setTime(firstDate.getTime() + validity*1000*24*60*60L);        CertificateValidity interval = new CertificateValidity(firstDate,                                                               lastDate);        certInfo.set(X509CertInfo.VALIDITY, interval);                // Make new serial number        certInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber            ((int)(firstDate.getTime()/1000)));        // Set owner and issuer fields        X500Name owner;        // Get the owner name from the certificate        owner = (X500Name)certInfo.get(X509CertInfo.SUBJECT + "." +                                       CertificateSubjectName.DN_NAME);        // Get the issuear name - the owner of the signing certificate        X500Name issuer;        issuer = (X500Name)signingCertInfo.get(X509CertInfo.SUBJECT + "." +                                           CertificateSubjectName.DN_NAME);                certInfo.set(X509CertInfo.ISSUER + "." +                     CertificateIssuerName.DN_NAME, issuer);                // The inner and outer signature algorithms have to match.        // The way we achieve that is really ugly, but there seems to be no        // other solution: We first sign the cert, then retrieve the        // outer sigalg and use it to set the inner sigalg        X509CertImpl newCert = new X509CertImpl(certInfo);        newCert.sign(privKey, sigAlgName);        AlgorithmId sigAlgid = (AlgorithmId)newCert.get(X509CertImpl.SIG_ALG);        certInfo.set(CertificateAlgorithmId.NAME + "." +                     CertificateAlgorithmId.ALGORITHM, sigAlgid);        // Sign the new certificate        newCert = new X509CertImpl(certInfo);        newCert.sign(privKey, sigAlgName);        // Store the new certificate as a single-element certificate chain        keyStore.setKeyEntry(signee_alias, privKey,                             (keyPass != null) ? keyPass : storePass,                             new Certificate[] { newCert });        System.err.println("New certificate signed & inserted into KeyStore!");        System.err.print(newCert.toString());        System.err.println();    }    /**     * Recovers (private) key associated with given alias.     *     * @return an array of objects, where the 1st element in the array is the     * recovered private key, and the 2nd element is the password used to     * recover it.     */    private static Object[] recoverPrivateKey(String alias, char[] storePass,                                              char[] keyPass, KeyStore keyStore)        throws KeyStoreException, NoSuchAlgorithmException,                UnrecoverableKeyException, Exception    {        Key key = null;                if (keyStore.containsAlias(alias) == false) {            throw new Exception("Alias <" + alias + "> does not exist");        }        if (keyStore.isKeyEntry(alias) == false) {            throw new Exception("Alias <" + alias + "> has no (private) key");        }        if (keyPass == null) {            // Try to recover the key using the keystore password            try {                key = keyStore.getKey(alias, storePass);                keyPass = storePass;            } catch (UnrecoverableKeyException e) {                throw new Exception("Invalid Key password entered");                // Did not work out, so prompt user for key password                // keyPass = getKeyPasswd(alias, null, null);                // key = keyStore.getKey(alias, keyPass);            }        } else {            key = keyStore.getKey(alias, keyPass);        }        if (!(key instanceof PrivateKey)) {            throw new Exception("Recovered key is not a private key");        }        return new Object[] {(PrivateKey)key, keyPass};    }}

⌨️ 快捷键说明

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