在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);
}
}
}