如何从pfx/p12文件中提取rsa密钥长度及其他相关信息 -凯发k8网页登录

 

在security编程中,有几种典型的密码交换信息文件格式:
der-encoded certificate: .cer, .crt
pem-encoded message: .pem
pkcs#12 personal information exchange: .pfx, .p12
pkcs#10 certification request: .p10
pkcs#7 cert request response: .p7r
pkcs#7 binary message: .p7b

.cer/.crt是用于存放证书,它是2进制形式存放的,不含私钥。
.pem跟crt/cer的区别是它以ascii来表示。
pfx/p12用于存放个人证书/私钥,他通常包含保护密码,2进制方式
p10是证书请求
p7r是ca对证书请求的回复,只用于导入
p7b以树状展示证书链(certificate chain),同时也支持单个证书,不含私钥。

其中,我介绍如何从p12/pfx文件中提取密钥对及其长度:
1,首先,读取pfx/p12文件(需要提供保护密码)
2,通过别名(alias,注意,所有证书中的信息项都是通过alias来提取的)提取你想要分析的证书链
3,再将其转换为一个以x509证书结构体
4,提取里面的项,如果那你的证书项放在第一位(单一证书),直接读取 x509certs[0](见下面的代码)这个x509certificate对象
5,x509certificate对象有很多方法,网友希望读取rsa密钥(公私钥)及其长度(见),那真是太easy了,
            x509certificate keypaircert = x509certs[0];
            int ikeysize = x509certutil.getcertificatekeylength(keypaircert);
            system.out.println("证书密钥算法=" keypaircert.getpublickey().getalgorithm());
            system.out.println("证书密钥长度=" ikeysize);

提取了他所需要的信息。

下面的代码来自于我的securex项目()的一部分,仅供参考,可以运行,但需要安装bouncycastle。

package  org.dev2dev.client.keypair;

import  java.io.file;
import  java.io.fileinputstream;
import  java.io.filenotfoundexception;
import  java.io.ioexception;
import  java.security.keystore;
import  java.security.keystoreexception;
import  java.security.nosuchalgorithmexception;
import  java.security.nosuchproviderexception;
import  java.security.security;
import  java.security.cert.certificate;
import  java.security.cert.certificateexception;
import  java.security.cert.x509certificate;
import  org.dev2dev.security.keytool.x509certutil;


public   class  loadkeyfrompkcs12  {
    
    
public   static   void  main(string[] args)  {
        
try   {
            
//  open an input stream on the keystore file
            string pfxfilename = " c:\\david.turing.pfx " ;
            string pfxpassword
= " 123456 " ;
            
            file fpkcs12 
=   null ;
            
if  (pfxfilename  !=   null {
                
//  open the file
                fpkcs12  =   new  file(pfxfilename);
            }

            
            
            fileinputstream fis 
=   new  fileinputstream(fpkcs12);

            
//  create a keystore object
            keystore keystore  =   null ;
            
try
            
{
                    
//  need bc provider for pkcs #12, bks and uber
                     if  (security.getprovider( " bc " ==   null )
                    
{
                        
throw   new  exception( " 不能load入bouncycastle! " );
                    }


                    keystore 
=  keystore.getinstance( " pkcs12 " " bc " );
            }

            
catch  (keystoreexception ex)
            
{
                 
throw   new  exception( " 不能正确解释pfx文件! " );
            }

            
catch  (nosuchproviderexception ex)
            
{
                
throw   new  exception( " security provider配置有误! " );
            }


            
try
            
{
                
//  load the file into the keystore
                keystore.load(fis, pfxpassword.tochararray());
            }

            
catch  (certificateexception ex)
            
{
                
throw   new  exception( " 证书格式问题! " );
            }

            
catch  (nosuchalgorithmexception ex)
            
{
                
throw   new  exception( " 算法不支持! " );
                }

            
catch  (filenotfoundexception ex)
            
{
                
throw   new  exception( " pfx文件没找到 " );
            }

            
catch  (ioexception ex)
            
{
                
throw   new  exception( " 读取pfx有误! " );
            }

            
            
// 获取我的证书链的中keyentry的别名
            certificate[] certs  =  keystore.getcertificatechain( " david.turing " );
            x509certificate[] x509certs 
=  x509certutil.convertcertificates(certs);

            
if  (x509certs  ==   null )
            
{
                
return ;
            }


            x509certs 
=  x509certutil.orderx509certchain(x509certs);

            x509certificate keypaircert 
=  x509certs[ 0 ];

            
int  ikeysize  =  x509certutil.getcertificatekeylength(keypaircert);
            system.out.println(
" 证书密钥算法= " keypaircert.getpublickey().getalgorithm());
            system.out.println(
" 证书密钥长度= " ikeysize);

        }
  catch  (exception e)  {
            e.printstacktrace();
        }
        
    }


}
另外,我会调用其他一个工具类x509utils来分析证书结构
package org.dev2dev.security.keytool;

import java.io.bytearrayinputstream;
import java.io.bytearrayoutputstream;
import java.io.file;
import java.io.fileinputstream;
import java.io.filenotfoundexception;
import java.io.ioexception;
import java.math.biginteger;
import java.security.generalsecurityexception;
import java.security.invalidkeyexception;
import java.security.keyfactory;
import java.security.keystore;
import java.security.keystoreexception;
import java.security.nosuchalgorithmexception;
import java.security.nosuchproviderexception;
import java.security.principal;
import java.security.privatekey;
import java.security.publickey;
import java.security.signatureexception;
import java.security.cert.crlexception;
import java.security.cert.certpath;
import java.security.cert.certificate;
import java.security.cert.certificateexception;
import java.security.cert.certificatefactory;
import java.security.cert.x509crl;
import java.security.cert.x509certificate;
import java.security.spec.dsapublickeyspec;
import java.security.spec.rsapublickeyspec;
import java.text.messageformat;
import java.util.arraylist;
import java.util.collection;
import java.util.date;
import java.util.enumeration;
import java.util.hashtable;
import java.util.iterator;
import java.util.resourcebundle;
import java.util.vector;

import org.bouncycastle.asn1.deroutputstream;
import org.bouncycastle.asn1.x509.x509name;
import org.bouncycastle.jce.pkcs10certificationrequest;
import org.bouncycastle.jce.x509principal;
import org.bouncycastle.jce.x509v1certificategenerator;

public final class x509certutil extends object
{
    
/** resource bundle */
    
private static resourcebundle m_res = resourcebundle.getbundle("org/dev2dev/security/keytool/resources");

    
/** type name for x.509 certificates */
    
private static final string x509_cert_type = "x.509";

    
/** pkcs #7 encoding name */
    
private static final string pkcs7_encoding = "pkcs7";

    
/** begin certificate in rfc 1421 encoding */
    
private static final string begin_cert = "-----begin certificate-----";

    
/** end certificate in rfc 1421 encoding */
    
private static final string end_cert = "-----end certificate-----";

    
/** the maximum length of lines in printable encoded certificates */
    
private static final int cert_line_length = 64;

    
/** begin certificate signing request */
    
private static final string begin_cert_req = "-----begin certificate request-----";

    
/** end certificate signing request */
    
private static final string end_cert_req = "-----end certificate request-----";

    
/** the maximum length of lines in certificate signing requests */
    
private static final int cert_req_line_length = 76;

    
/**
     * private to prevent construction.
     
*/

    
private x509certutil() {}

    
/**
     * load one or more certificates from the specified file.
     *
     * 
@param fcertfile the file to load certificates from
     * 
@return the certificates
     * 
@throws cryptoexception problem encountered while loading the certificate(s)
     * 
@throws filenotfoundexception if the certificate file does not exist,
     *                               is a directory rather than a regular
     *                               file, or for some other reason cannot
     *                               be opened for reading
     * 
@throws ioexception an i/o error occurred
     
*/

    
public static x509certificate[] loadcertificates(file fcertfile)
        
throws cryptoexception, filenotfoundexception, ioexception
    
{
        vector vcerts 
= new vector();

        fileinputstream fis 
= new fileinputstream(fcertfile);

        
try
        
{
            certificatefactory cf 
= certificatefactory.getinstance(x509_cert_type);

            collection coll 
= cf.generatecertificates(fis);
            iterator iter 
= coll.iterator();

            
while (iter.hasnext())
            
{
                x509certificate cert 
= (x509certificate)iter.next();
                
if (cert != null)
                
{
                    vcerts.add(cert);
                }

            }

        }

        
catch (certificateexception ex)
        
{
            
throw new cryptoexception(messageformat.format(m_res.getstring("noloadcertificate.exception.message"), new string[]{ex.getmessage()}), ex);
        }

        
finally
        
{
            fis.close();
        }


        
return (x509certificate[])vcerts.toarray(new x509certificate[vcerts.size()]);
    }


    
/**
     * load a crl from the specified file.
     *
     * 
@param fcrlfile the file to load crl from
     * 
@return the crl
     * 
@throws cryptoexception problem encountered while loading the certificate(s)
     * 
@throws filenotfoundexception if the crl file does not exist,
     *                               is a directory rather than a regular
     *                               file, or for some other reason cannot
     *                               be opened for reading
     * 
@throws ioexception an i/o error occurred
     
*/

    
public static x509crl loadcrl(file fcrlfile)
        
throws cryptoexception, filenotfoundexception, ioexception
    
{
        fileinputstream fis 
= new fileinputstream(fcrlfile);

        
try
        
{
            certificatefactory cf 
= certificatefactory.getinstance(x509_cert_type);
            x509crl crl 
= (x509crl)cf.generatecrl(fis);
            
return crl;
        }

        
catch (certificateexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("noloadcrl.exception.message"), ex);
        }

        
catch (crlexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("noloadcrl.exception.message"), ex);
        }

        
finally
        
{
            fis.close();
        }

    }


    
/**
     * convert the supplied array of certificate objects into x509certificate objects.
     *
     * 
@param certsin the certificate objects
     * 
@return the converted x509certificate objects
     * 
@throws cryptoexception a problem occurred during the conversion
     
*/

    
public static x509certificate[] convertcertificates(certificate[] certsin)
        
throws cryptoexception
    
{
        x509certificate[] certsout 
= new x509certificate[certsin.length];

        
for (int icnt=0; icnt < certsin.length; icnt)
        
{
            certsout[icnt] 
= convertcertificate(certsin[icnt]);
        }


        
return certsout;
    }


    
/**
     * convert the supplied certificate object into an x509certificate object.
     *
     * 
@param certin the certificate object
     * 
@return the converted x509certificate object
     * 
@throws cryptoexception a problem occurred during the conversion
     
*/

    
public static x509certificate convertcertificate(certificate certin)
        
throws cryptoexception
    
{
        
try
        
{
            certificatefactory cf 
= certificatefactory.getinstance(x509_cert_type);
            bytearrayinputstream bais 
= new bytearrayinputstream(certin.getencoded());
            
return (x509certificate)cf.generatecertificate(bais);
        }

        
catch (certificateexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("noconvertcertificate.exception.message"), ex);
        }

    }


    
/**
     * attempt to order the supplied array of x.509 certificates in issued to
     * to issued from order.
     *
     * 
@param certs the x.509 certificates in order
     * 
@return the ordered x.509 certificates
     
*/

    
public static x509certificate[] orderx509certchain(x509certificate certs[])
    
{
        
int iordered = 0;
        x509certificate[] tmpcerts 
= (x509certificate[])certs.clone();
        x509certificate[] orderedcerts 
= new x509certificate[certs.length];

        x509certificate issuercert 
= null;

        
// find the root issuer (ie certificate where issuer is the same as subject)
        for (int icnt=0; icnt < tmpcerts.length; icnt)
        
{
            x509certificate acert 
= tmpcerts[icnt];
            
if (acert.getissuerdn().equals(acert.getsubjectdn()))
            
{
                issuercert 
= acert;
                orderedcerts[iordered] 
= issuercert;
                iordered
;
            }

        }


        
// couldn't find a root issuer so just return the unordered array
        if (issuercert == null)
        
{
            
return certs;
        }


        
// keep making passes through the array of certificates lookign for the
        
// next certificate in the chain until the links run out
        while (true)
        
{
            
boolean bfoundnext = false;
            
for (int icnt=0; icnt < tmpcerts.length; icnt)
            
{
                x509certificate acert 
= tmpcerts[icnt];

                
// is this certificate the next in the chain?
                if ((acert.getissuerdn().equals(issuercert.getsubjectdn())) && (acert != issuercert))
                
{
                    
// yes
                    issuercert = acert;
                    orderedcerts[iordered] 
= issuercert;
                    iordered
;
                    bfoundnext 
= true;
                    
break;
                }

            }

            
if (!bfoundnext)
            
{
                
break;
            }

        }


        
// resize array
        tmpcerts = new x509certificate[iordered];
        system.arraycopy(orderedcerts, 
0, tmpcerts, 0, iordered);

        
// reverse the order of the array
        orderedcerts = new x509certificate[iordered];

        
for (int icnt=0; icnt < iordered; icnt)
        
{
            orderedcerts[icnt] 
= tmpcerts[tmpcerts.length - 1 - icnt];
        }


        
return orderedcerts;
    }


    
/**
     * der encode a certificate.
     *
     * 
@return the binary encoding
     * 
@param cert the certificate
     * 
@throws cryptoexception if there was a problem encoding the certificate
     
*/

    
public static byte[] getcertencodedder(x509certificate cert) throws cryptoexception
    
{
        
try
        
{
            
return cert.getencoded();
        }

        
catch (certificateexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("noderencode.exception.message"), ex);
        }

    }


    
/**
     * base-64 encode a certificate.
     *
     * 
@return the printable encoding
     * 
@param cert the certificate
     * 
@throws cryptoexception if there was a problem encoding the certificate
     
*/

    
public static string getcertencodedbase64(x509certificate cert) throws cryptoexception
    
{
        
try
        
{
            
// get base 64 encoding of certificate
            string stmp = new string(base64.encode(cert.getencoded()));

            
// certificate encodng is bounded by a header and footer
            string sencoded = begin_cert  "\n";

            
// limit line lengths between header and footer
            for (int icnt=0; icnt < stmp.length(); icnt  = cert_line_length)
            
{
                
int ilinelength;

                
if ((icnt  cert_line_length) > stmp.length())
                
{
                    ilinelength 
= (stmp.length() - icnt);
                }

                
else
                
{
                    ilinelength 
= cert_line_length;
                }


                sencoded 
= stmp.substring(icnt, (icnt  ilinelength))  "\n";
            }


            
// footer
            sencoded  = end_cert  "\n";

            
return sencoded;
        }

        
catch (certificateexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("nobase64encode.exception.message"), ex);
        }

        
catch (ioexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("nobase64encode.exception.message"), ex);
        }

    }


    
/**
     * pkcs #7 encode a certificate.
     *
     * 
@return the encoding
     * 
@param cert the certificate
     * 
@throws cryptoexception if there was a problem encoding the certificate
     
*/

    
public static byte[] getcertencodedpkcs7(x509certificate cert)
        
throws cryptoexception
    
{
        
return getcertsencodedpkcs7(new x509certificate[] {cert});
    }


    
/**
     * pkcs #7 encode a number of certificates.
     *
     * 
@return the encoding
     * 
@param certs the certificates
     * 
@throws cryptoexception if there was a problem encoding the certificates
     
*/

    
public static byte[] getcertsencodedpkcs7(x509certificate[] certs)
        
throws cryptoexception
    
{
        
try
        
{
             arraylist alcerts 
= new arraylist();

             
for (int icnt=0; icnt < certs.length; icnt)
             
{
                 alcerts.add(certs[icnt]);
             }


             certificatefactory cf 
= certificatefactory.getinstance(x509_cert_type);
             certpath cp 
= cf.generatecertpath(alcerts);

             
return cp.getencoded(pkcs7_encoding);
        }

        
catch (certificateexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("nopkcs7encode.exception.message"), ex);
        }

    }


    
/**
     * generate a self-signed x509 version 1 certificate for the supplied key
     * pair and signature algorithm.
     *
     * 
@return the generated certificate
     * 
@param scommonname common name certficate attribute
     * 
@param sorganisationunit organisation unit certificate attribute
     * 
@param sorganisation organisation certificate attribute
     * 
@param slocality locality certificate
     * 
@param sstate state certificate attribute
     * 
@param scountrycode country code certificate attribute
     * 
@param ivalidity validity period of cerficate in days
     * 
@param publickey public part of key pair
     * 
@param privatekey private part of key pair
     * 
@param signaturetype signature type
     * 
@throws cryptoexception if there was a problem generating the certificate
     
*/

    
public static x509certificate generatecert(string scommonname, string sorganisationunit,
                                               string sorganisation, string slocality,
                                               string sstate, string scountrycode,
                                               
int ivalidity, publickey publickey,
                                               privatekey privatekey, signaturetype signaturetype)
        
throws cryptoexception
    
{
        
// holds certificate attributes
        hashtable attrs = new hashtable();
        vector vorder 
= new vector();

        
// load certificate attributes
        if (scommonname != null)
        
{
            attrs.put(x509principal.cn, scommonname);
            vorder.add(
0, x509principal.cn);
        }


        
if (sorganisationunit != null)
        
{
            attrs.put(x509principal.ou, sorganisationunit);
            vorder.add(
0, x509principal.ou);
        }


        
if (sorganisation != null)
        
{
            attrs.put(x509principal.o, sorganisation);
            vorder.add(
0, x509principal.o);
        }


        
if (slocality != null)
        
{
            attrs.put(x509principal.l, slocality);
            vorder.add(
0, x509principal.l);
        }


        
if (sstate != null)
        
{
            attrs.put(x509principal.st, sstate);
            vorder.add(
0, x509principal.st);
        }


        
if (scountrycode != null)
        
{
            attrs.put(x509principal.c, scountrycode);
            vorder.add(
0, x509principal.c);
        }


        
// get an x509 version 1 certificate generator
        x509v1certificategenerator certgen = new x509v1certificategenerator();

        
// load the generator with generation parameters

        
// set the issuer distinguished name
        certgen.setissuerdn(new x509principal(vorder, attrs));

        
// valid before and after dates now to ivalidity days in the future
        certgen.setnotbefore(new date(system.currenttimemillis()));
        certgen.setnotafter(
new date(system.currenttimemillis()  ((long)ivalidity * 24 * 60 * 60 * 1000)));

        
// set the subject distinguished name (same as issuer for our purposes)
        certgen.setsubjectdn(new x509principal(vorder, attrs));

        
// set the public key
        certgen.setpublickey(publickey);

        
// set the algorithm
        certgen.setsignaturealgorithm(signaturetype.tostring());

        
// set the serial number
        certgen.setserialnumber(generatex509serialnumber());

        
try
        
{
            
// generate an x.509 certificate, based on the current issuer and
            
// subject
            x509certificate cert = certgen.generatex509certificate(privatekey);

            
// return the certificate
            return cert;
        }

        
// something went wrong
        catch (signatureexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("certificategenfailed.exception.message"), ex);
        }

        
catch (invalidkeyexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("certificategenfailed.exception.message"), ex);
        }

    }


    
/**
     * generate a unique serial number for use as an x509 serial number.
     *
     * 
@return the unique serial number
     
*/

    
private static biginteger generatex509serialnumber()
    
{
        
// time in seconds
        return new biginteger(long.tostring(system.currenttimemillis() / 1000));
    }


    
/**
     * create a pkcs #10 certificate signing request (csr) using the supplied
     * certificate and private key.
     *
     * 
@param cert the certificate
     * 
@param privatekey the private key
     * 
@throws cryptoexception if there was a problem generating the csr
     * 
@return the csr
     
*/

    
public static string generatepkcs10csr(x509certificate cert, privatekey privatekey)
        
throws cryptoexception
    
{
        x509name subject 
= new x509name(cert.getsubjectdn().tostring());

        
try
        
{
            pkcs10certificationrequest csr 
=
                
new pkcs10certificationrequest(cert.getsigalgname(),
                                               subject,
                                               cert.getpublickey(),
                                               
null,
                                               privatekey);
            
if (!csr.verify())
            
{
                
throw new cryptoexception(m_res.getstring("noverifycsr.exception.message"));
            }


            
// get base 64 encoding of csr
            bytearrayoutputstream baos = new bytearrayoutputstream();
            deroutputstream deros 
= new deroutputstream(baos);
            deros.writeobject(csr.getderobject());
            string stmp 
= new string(base64.encode(baos.tobytearray()));

            
// csr is bounded by a header and footer
            string scsr = begin_cert_req  "\n";

            
// limit line lengths between header and footer
            for (int icnt=0; icnt < stmp.length(); icnt  = cert_req_line_length)
            
{
                
int ilinelength;

                
if ((icnt  cert_req_line_length) > stmp.length())
                
{
                    ilinelength 
= (stmp.length() - icnt);
                }

                
else
                
{
                    ilinelength 
= cert_req_line_length;
                }


                scsr 
= stmp.substring(icnt, (icnt  ilinelength))  "\n";
            }


            
// footer
            scsr  = end_cert_req  "\n";

            
return scsr;
        }

        
catch (nosuchproviderexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("nogeneratecsr.exception.message"), ex);
        }

        
catch (nosuchalgorithmexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("nogeneratecsr.exception.message"), ex);
        }

        
catch (signatureexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("nogeneratecsr.exception.message"), ex);
        }

        
catch (invalidkeyexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("nogeneratecsr.exception.message"), ex);
        }

        
catch (ioexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("nogeneratecsr.exception.message"), ex);
        }

    }


    
/**
     * verify that one x.509 certificate was signed using the private key that
     * corresponds to the public key of a second certificate.
     *
     * 
@return true if the first certificate was signed by private key
     *         corresponding to the second signature
     * 
@param signedcert the signed certificate
     * 
@param signingcert the signing certificate
     * 
@throws cryptoexception if there was a problem verifying the signature.
     
*/

    
public static boolean verifycertificate(x509certificate signedcert, x509certificate signingcert)
        
throws cryptoexception
    
{
        
try
        
{
            signedcert.verify(signingcert.getpublickey());
        }

        
// verification failed
        catch (invalidkeyexception ex)
        
{
            
return false;
        }

        
// verification failed
        catch (signatureexception ex)
        
{
            
return false;
        }

        
// problem verifying
        catch (nosuchproviderexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("noverifycertificate.exception.message"), ex);
        }

        
catch (nosuchalgorithmexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("noverifycertificate.exception.message"), ex);
        }

        
catch (certificateexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("noverifycertificate.exception.message"), ex);
        }

        
return true;
    }


    
/**
     * check whether or not a trust path exists between the supplied x.509 certificate and
     * and the supplied keystores based on the trusted certificates contained
     * therein, ie that a chain of trust exists between the supplied certificate
     * and a self-signed trusted certificate in the keystores.
     *
     * 
@return the trust chain, or null if trust could not be established
     * 
@param cert the certificate
     * 
@param keystores the keystores
     * 
@throws cryptoexception if there is a problem establishing trust
     
*/

    
public static x509certificate[] establishtrust(keystore keystores[], x509certificate cert)
        
throws cryptoexception
    
{
        
// extract all certificates from the keystores creating
        vector kscerts = new vector();
        
for (int icnt=0; icnt < keystores.length; icnt)
        
{
            kscerts.addall(extractcertificates(keystores[icnt]));
        }


        
// try and establish trust against the set of all certificates
        return establishtrust(kscerts, cert);
    }


    
/**
     * check whether or not a trust path exists between the supplied x.509 certificate and
     * and the supplied comparison certificates based on the trusted certificates contained
     * therein, ie that a chain of trust exists between the supplied certificate
     * and a self-signed trusted certificate in the comparison set.
     *
     * 
@return the trust chain, or null if trust could not be established
     * 
@param cert the certificate
     * 
@param vcompcerts the comparison set of certificates
     * 
@throws cryptoexception if there is a problem establishing trust
     
*/

    
private static x509certificate[] establishtrust(vector vcompcerts, x509certificate cert)
        
throws cryptoexception
    
{
        
// for each comparison certificate
        for (int icnt=0; icnt < vcompcerts.size(); icnt)
        
{
            x509certificate compcert 
= (x509certificate)vcompcerts.get(icnt);

            
// check if the comparison certificate's subject is the same as the
            
// certificate's issuer
            if (cert.getissuerdn().equals(compcert.getsubjectdn()))
            
{
                
// if so verify with the comparison certificate's corresponding
                
// private key was used to sign the certificate
                if (x509certutil.verifycertificate(cert, compcert))
                
{
                    
// if the keystore certificate is self-signed then a
                    
// chain of trust exists
                    if (compcert.getsubjectdn().equals(compcert.getissuerdn()))
                    
{
                        
return new x509certificate[]{cert, compcert};
                    }

                    
// otherwise try and establish a chain of trust for
                    
// the comparison certificate against the other comparison certificates
                    else
                    
{
                        x509certificate[] tmpchain 
= establishtrust(vcompcerts, compcert);
                        
if (tmpchain != null)
                        
{
                            x509certificate[] trustchain 
= new x509certificate[tmpchain.length  1];

                            trustchain[
0= cert;

                            
for (int icntinr=1; icntinr <= tmpchain.length; icntinr)
                            
{
                                trustchain[icntinr] 
= tmpchain[icntinr-1];
                            }


                            
return trustchain;
                        }

                    }

                }

            }

        }


        
// no chain of trust
        return null;
    }


    
/**
     * extract a copy of all trusted certificates contained within the supplied keystore.
     *
     * 
@param keystore the keystore
     * 
@return the extracted certificates
     * 
@throws cryptoexception if a problem is encountered extracting the certificates
     
*/

    
private static vector extractcertificates(keystore keystore) throws cryptoexception
    
{
        
try
        
{
            
// for each keystore certificate
            enumeration enum2 = keystore.aliases();

            vector vcerts 
= new vector();

            
while (enum2.hasmoreelements())
            
{
                string salias 
= (string)enum2.nextelement();

                
if (keystore.iscertificateentry(salias))
                
{
                    vcerts.add(x509certutil.convertcertificate(keystore.getcertificate(salias)));
                }

            }


            
return vcerts;
        }

        
catch (keystoreexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("noextractcertificates.exception.message"), ex);
        }

    }


    
/**
     * check whether or not a trusted certificate in the supplied keystore
     * matches the the supplied x.509 certificate.
     *
     * 
@return the alias of the matching certificate in the keystore or null
     *         if there is no match
     * 
@param cert the certificate
     * 
@param keystore the keystore
     * 
@throws cryptoexception if there is a problem establishing trust
     
*/

    
public static string matchcertificate(keystore keystore, x509certificate cert)
        
throws cryptoexception
    
{
        
try
        
{
            enumeration enum2 
= keystore.aliases();

            
while (enum2.hasmoreelements())
            
{
                string salias 
= (string)enum2.nextelement();
                
if (keystore.iscertificateentry(salias))
                
{
                    x509certificate compcert 
= x509certutil.convertcertificate(keystore.getcertificate(salias));

                    
if (cert.equals(compcert))
                    
{
                        
return salias;
                    }

                }

            }

            
return null;
        }

        
catch (keystoreexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("nomatchcertificate.exception.message"), ex);
        }

    }


    
/**
     * for a given x.509 certificate get a representative alias for it in a keystore.
     * for a self-signed certificate this will be the subject's common name (if
     * any).  for a non-self-signed certificate it will be the subject's common
     * name followed by the issuer's common name in brackets.  alaises will
     * always be in lower case.
     *
     * 
@param cert the certificate
     * 
@return the alias or a blank string if none could be worked out
     
*/

    
public static string getcertificatealias(x509certificate cert)
    
{
        
// get the subject and issuer distinguished names
        principal subject = cert.getsubjectdn();
        principal issuer 
= cert.getissuerdn();

        
// get the subject's common name
        string ssubject = subject.getname();
        string ssubjectcn 
= "";
        
int icn = ssubject.indexof("cn=");
        
if (icn != -1)
        
{
            icn 
= 3;
            
int iendcn = ssubject.indexof("", icn);
            
if (iendcn != -1)
            
{
                ssubjectcn 
= ssubject.substring(icn, iendcn).tolowercase();
            }

            
else
            
{
                ssubjectcn 
= ssubject.substring(icn).tolowercase();
            }

        }


        
// get the issuer's common name
        string sissuer = issuer.getname();
        string sissuercn 
= "";
        icn 
= sissuer.indexof("cn=");
        
if (icn != -1)
        
{
            icn 
= 3;
            
int iendcn = sissuer.indexof("", icn);
            
if (iendcn != -1)
            
{
                sissuercn 
= sissuer.substring(icn, iendcn).tolowercase();
            }

            
else
            
{
                sissuercn 
= sissuer.substring(icn).tolowercase();
            }

        }


        
// could not get a subject cn - return blank
        if (ssubjectcn.length() == 0)
        
{
            
return "";
        }


        
// self-signed certificate or could not get an issuer cn
        if ((subject.equals(issuer)) || (sissuercn.length() == 0))
        
{
            
// alias is the subject cn
            return ssubjectcn;
        }

        
// non-self-signed certificate
        else
        
{
            
// alias is the subject cn followed by the issuer cn in brackets
            return messageformat.format("{0} ({1})"new string[]{ssubjectcn, sissuercn});
        }

    }


    
/**
     * for a given x.509 certificate get the keysize of its public key.
     *
     * 
@param cert the certificate
     * 
@return the keysize
     * 
@throws cryptoexception if there is a problem getting the keysize
     
*/

    
public static int getcertificatekeylength(x509certificate cert)
        
throws cryptoexception
    
{
        
try
        
{
            
// get the certificate's public key
            publickey pubkey = cert.getpublickey();

            
// get the public key algorithm
            string salgorithm = pubkey.getalgorithm();

            
// if the algorithm is rsa then use a keyfactory to create an rsa public
            
// key spec and get the keysize from the modulus length in bits
            if (salgorithm.equals(keypairtype.rsa.tostring()))
            
{
                keyfactory keyfact 
= keyfactory.getinstance(salgorithm);
                rsapublickeyspec keyspec 
= (rsapublickeyspec)keyfact.getkeyspec(pubkey, rsapublickeyspec.class);
                biginteger modulus 
= keyspec.getmodulus();
                
return modulus.tostring(2).length();
            }

            
// if the algorithm is rsa then use a keyfactory to cretae an dsa public
            
// key spec and get the keysize from the prime length in bits
            else if (salgorithm.equals(keypairtype.dsa.tostring()))
            
{
                keyfactory keyfact 
= keyfactory.getinstance(salgorithm);
                dsapublickeyspec keyspec 
= (dsapublickeyspec)keyfact.getkeyspec(pubkey, dsapublickeyspec.class);
                biginteger prime 
= keyspec.getp();
                
return prime.tostring(2).length();
            }

            
// otherwise cannot calculate keysize
            else
            
{
                
throw new cryptoexception(messageformat.format(m_res.getstring("nocertificatepublickeysizeunrecogalg.exception.message"), new object[]{salgorithm}));
            }

        }

        
catch (generalsecurityexception ex)
        
{
            
throw new cryptoexception(m_res.getstring("nocertificatepublickeysize.exception.message"), ex);
        }

    }

}




   
            

posted on 2006-04-29 09:38 david.turing 阅读(17048) 评论(13)     所属分类: security领域

# re: 如何从pfx/p12文件中提取rsa密钥长度及其他相关信息 2006-05-25 21:18

这个方法我是知道的。只是因为我上次的工程,需要输入的数据超过了117个字节,结果造成了异常,我以为是我的密钥长度不对,所以希望能够人工的算出密钥长度,不过还是很感谢你。
后来我才发现,原来是因为我输入的数据长度,超过了128个字节,而我使用的1024位的密钥,所以才造成了加密失败。不过你前面解释的证书体系还是非常不错的。再次感谢你。  回复     

# re: 如何从pfx/p12文件中提取rsa密钥长度及其他相关信息 2006-05-29 22:54

hehe, 你必须自己处理rsa的inblock size和outblock size,1024bit的rsa加密算法,假定你用pkcs,需要使用117 inblock->128 outblock是必须遵循的,用128byte的输入显然是溢出了:)  回复     

# re: 如何从pfx/p12文件中提取rsa密钥长度及其他相关信息 2006-06-26 19:45

看了你的blog上的很多文章,写的真不错,向你学习ing....

我现在遇到一个问题,希望你能帮帮我,已经捆饶我很久了。
我使用cryptoapi通过csp访问到usbkey,然后对一段数据进行签名,得到的签名值(好象是pkcs#7 ),然后我在服务器端验证签名,使用java语言,已经有证书,我得到证书里的公钥,被签名的明文我也有。为什么老是验证通不过呢,仔细看过代码(也让别人看过我的java代码)不应该有错。

我怀疑是不是通过csp签名后的签名值和java验证签名时传入的签名值有差异。

你能帮我吗?
我的信箱是yangnan2004@163.com  回复     

# re: 如何从pfx/p12文件中提取rsa密钥长度及其他相关信息 2006-08-03 06:49

我的证书密码忘了~~~导入不了~能帮我找找吗??

好心人,善良人,看到一定会帮我的~~我的qq是:86661177

  回复     

# re: 如何从pfx/p12文件中提取rsa密钥长度及其他相关信息 2006-08-03 09:27

cboys, 你的问题太经典了
原则上,如果你调用capi访问usbkey产生签名,签名是pkcs#7,windows是little-endian, java处理的是big-endian的,你需要先通过base64处理一下签名,然后再发送到服务器。  回复     

# re: 如何从pfx/p12文件中提取rsa密钥长度及其他相关信息 2006-08-03 09:29

pfx证书密码忘了,那没办法帮你啊  回复     

# re: 如何从pfx/p12文件中提取rsa密钥长度及其他相关信息 2006-08-23 15:49

没有密码怎么从 pfx 获取公钥?  回复     

# re: 如何从pfx/p12文件中提取rsa密钥长度及其他相关信息 2006-12-04 14:31

写的非常不错,我也刚研究pki没多久  回复     

# re: 如何从pfx/p12文件中提取rsa密钥长度及其他相关信息 2007-04-12 18:32

向各位好心人请教个问题,我的.pfx证书在导入的时侯提示:发生一个内部错误,导入的私钥需要一个加密服务提供程序,但系统上没有安装该程序。
我想知道我应该安装什么?拜谢诸位,  回复     

# cer fil 2007-08-30 20:31

请问有了一个p12文件,如何生成一个cer或crt文件,可以用p12来生成也可以自己生成,只要能生成cer文件即可.

需用jaca程序实现谢谢shichling@126.com  回复     

# re: 如何从pfx/p12文件中提取rsa密钥长度及其他相关信息 2007-08-30 21:46

3再将其转换为一个以x509证书结构体
这一条怎么实现? 即p12 -> cer/crt格式?  回复     

# re: 如何从pfx/p12文件中提取rsa密钥长度及其他相关信息 2007-08-30 21:47

3再将其转换为一个以x509证书结构体
如果可以请发送到 shichling@126.com, 谢谢  回复     

# re: 如何从pfx/p12文件中提取rsa密钥长度及其他相关信息 2008-08-28 13:57

太好了兄弟,找的就是这个,爱死你了!哈哈哈哈哈哈  回复     

导航

统计

常用链接

留言簿(109)

我参与的团队

随笔分类(126)

随笔档案(155)

文章分类(9)

文章档案(19)

相册

搜索

积分与排名

最新随笔

最新评论

阅读排行榜

评论排行榜

网站地图