如何从pfx/p12文件中提取RSA密钥长度及其他相关信息

在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对象有很多方法,tain198127网友希望读取RSA密钥(公私钥)及其长度(见http://www.matrix.org.cn/thread.shtml?topicId=43786&forumId=55&#reply),那真是太Easy了,
            X509Certificate keyPairCert = x509Certs[0];
            int iKeySize = X509CertUtil.getCertificateKeyLength(keyPairCert);
            System.out.println("证书密钥算法="+keyPairCert.getPublicKey().getAlgorithm());
            System.out.println("证书密钥长度="+iKeySize);

提取了他所需要的信息。

下面的代码来自于我的SecureX项目(https://sourceforge.net/projects/securex)的一部分,仅供参考,可以运行,但需要安装BouncyCastle。

None.gif package  org.dev2dev.client.keypair;
None.gif
None.gif
import  java.io.File;
None.gif
import  java.io.FileInputStream;
None.gif
import  java.io.FileNotFoundException;
None.gif
import  java.io.IOException;
None.gif
import  java.security.KeyStore;
None.gif
import  java.security.KeyStoreException;
None.gif
import  java.security.NoSuchAlgorithmException;
None.gif
import  java.security.NoSuchProviderException;
None.gif
import  java.security.Security;
None.gif
import  java.security.cert.Certificate;
None.gif
import  java.security.cert.CertificateException;
None.gif
import  java.security.cert.X509Certificate;
None.gif
import  org.dev2dev.security.keytool.X509CertUtil;
None.gif
None.gif
ExpandedBlockStart.gifContractedBlock.gif
public   class  LoadKeyFromPKCS12  dot.gif {
InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public   static   void  main(String[] args)  dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif        
try   dot.gif {
InBlock.gif            
//  Open an input stream on the keystore file
InBlock.gif
            String pfxFileName = " c:\\david.turing.pfx " ;
InBlock.gif            String pfxPassword
= " 123456 " ;
InBlock.gif            
InBlock.gif            File fPkcs12 
=   null ;
ExpandedSubBlockStart.gifContractedSubBlock.gif            
if  (pfxFileName  !=   null dot.gif {
InBlock.gif                
//  Open the file
InBlock.gif
                fPkcs12  =   new  File(pfxFileName);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
InBlock.gif            
InBlock.gif            FileInputStream fis 
=   new  FileInputStream(fPkcs12);
InBlock.gif
InBlock.gif            
//  Create a keystore object
InBlock.gif
            KeyStore keyStore  =   null ;
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif {
InBlock.gif                    
//  Need BC provider for PKCS #12, BKS and UBER
InBlock.gif
                     if  (Security.getProvider( " BC " ==   null )
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif {
InBlock.gif                        
throw   new  Exception( " 不能Load入BouncyCastle! " );
ExpandedSubBlockEnd.gif                    }

InBlock.gif
InBlock.gif                    keyStore 
=  KeyStore.getInstance( " PKCS12 " " BC " );
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch  (KeyStoreException ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif {
InBlock.gif                 
throw   new  Exception( " 不能正确解释pfx文件! " );
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch  (NoSuchProviderException ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif {
InBlock.gif                
throw   new  Exception( " Security Provider配置有误! " );
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif {
InBlock.gif                
//  Load the file into the keystore
InBlock.gif
                keyStore.load(fis, pfxPassword.toCharArray());
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch  (CertificateException ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif {
InBlock.gif                
throw   new  Exception( " 证书格式问题! " );
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch  (NoSuchAlgorithmException ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif {
InBlock.gif                
throw   new  Exception( " 算法不支持! " );
ExpandedSubBlockEnd.gif                }

InBlock.gif            
catch  (FileNotFoundException ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif {
InBlock.gif                
throw   new  Exception( " pfx文件没找到 " );
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch  (IOException ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif {
InBlock.gif                
throw   new  Exception( " 读取pfx有误! " );
ExpandedSubBlockEnd.gif            }

InBlock.gif            
InBlock.gif            
// 获取我的证书链的中keyEntry的别名
InBlock.gif
            Certificate[] certs  =  keyStore.getCertificateChain( " david.turing " );
InBlock.gif            X509Certificate[] x509Certs 
=  X509CertUtil.convertCertificates(certs);
InBlock.gif
InBlock.gif            
if  (x509Certs  ==   null )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif {
InBlock.gif                
return ;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            x509Certs 
=  X509CertUtil.orderX509CertChain(x509Certs);
InBlock.gif
InBlock.gif            X509Certificate keyPairCert 
=  x509Certs[ 0 ];
InBlock.gif
InBlock.gif            
int  iKeySize  =  X509CertUtil.getCertificateKeyLength(keyPairCert);
InBlock.gif            System.out.println(
" 证书密钥算法= " + keyPairCert.getPublicKey().getAlgorithm());
InBlock.gif            System.out.println(
" 证书密钥长度= " + iKeySize);
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        }
  catch  (Exception e)  dot.gif {
InBlock.gif            e.printStackTrace();
ExpandedSubBlockEnd.gif        }
        
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}
另外,我会调用其他一个工具类X509Utils来分析证书结构
None.gif package  org.dev2dev.security.keytool;
None.gif
None.gif
import  java.io.ByteArrayInputStream;
None.gif
import  java.io.ByteArrayOutputStream;
None.gif
import  java.io.File;
None.gif
import  java.io.FileInputStream;
None.gif
import  java.io.FileNotFoundException;
None.gif
import  java.io.IOException;
None.gif
import  java.math.BigInteger;
None.gif
import  java.security.GeneralSecurityException;
None.gif
import  java.security.InvalidKeyException;
None.gif
import  java.security.KeyFactory;
None.gif
import  java.security.KeyStore;
None.gif
import  java.security.KeyStoreException;
None.gif
import  java.security.NoSuchAlgorithmException;
None.gif
import  java.security.NoSuchProviderException;
None.gif
import  java.security.Principal;
None.gif
import  java.security.PrivateKey;
None.gif
import  java.security.PublicKey;
None.gif
import  java.security.SignatureException;
None.gif
import  java.security.cert.CRLException;
None.gif
import  java.security.cert.CertPath;
None.gif
import  java.security.cert.Certificate;
None.gif
import  java.security.cert.CertificateException;
None.gif
import  java.security.cert.CertificateFactory;
None.gif
import  java.security.cert.X509CRL;
None.gif
import  java.security.cert.X509Certificate;
None.gif
import  java.security.spec.DSAPublicKeySpec;
None.gif
import  java.security.spec.RSAPublicKeySpec;
None.gif
import  java.text.MessageFormat;
None.gif
import  java.util.ArrayList;
None.gif
import  java.util.Collection;
None.gif
import  java.util.Date;
None.gif
import  java.util.Enumeration;
None.gif
import  java.util.Hashtable;
None.gif
import  java.util.Iterator;
None.gif
import  java.util.ResourceBundle;
None.gif
import  java.util.Vector;
None.gif
None.gif
import  org.bouncycastle.asn1.DEROutputStream;
None.gif
import  org.bouncycastle.asn1.x509.X509Name;
None.gif
import  org.bouncycastle.jce.PKCS10CertificationRequest;
None.gif
import  org.bouncycastle.jce.X509Principal;
None.gif
import  org.bouncycastle.jce.X509V1CertificateGenerator;
None.gif
None.gif
public   final   class  X509CertUtil  extends  Object
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** *//** Resource bundle */
InBlock.gif    
private static ResourceBundle m_res = ResourceBundle.getBundle("org/dev2dev/security/keytool/resources");
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** *//** Type name for X.509 certificates */
InBlock.gif    
private static final String X509_CERT_TYPE = "X.509";
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** *//** PKCS #7 encoding name */
InBlock.gif    
private static final String PKCS7_ENCODING = "PKCS7";
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** *//** Begin certificate in RFC 1421 encoding */
InBlock.gif    
private static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** *//** End certificate in RFC 1421 encoding */
InBlock.gif    
private static final String END_CERT = "-----END CERTIFICATE-----";
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** *//** The maximum length of lines in printable encoded certificates */
InBlock.gif    
private static final int CERT_LINE_LENGTH = 64;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** *//** Begin certificate signing request */
InBlock.gif    
private static final String BEGIN_CERT_REQ = "-----BEGIN CERTIFICATE REQUEST-----";
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** *//**
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值