初学certificate

来源:互联网 发布:win7网络上有红叉 编辑:程序博客网 时间:2024/06/14 09:04

    昨晚刚向朋友请教电子证书和电子证书链的转变是如何完成的,今天就看到了这篇文章。转之。

    出道半年多,感觉java要学习好多东西,可是又不知道从何入手? 工作的任务仅仅是维护项目,也仅学到些表面东西,干脆自己研究,把学到的表面东西更加深究。又后来发现如果不结合项目,很容易忘记,所以决定把自己的学习一步步写下来,初次学习,肯定有很多错误和不足的地方,希望大家多多指导。

    首先接触证书,直面理解它的作用就是身份验证。但不知道它又是如何实现,它是个什么东西?于是在网上翻查资料,于是理解到一些,如下:

    第一个需要理解的概念,密钥对:公钥和私钥
    密钥对是一起产生的,可以互相加密解密。对于证书来说,私钥由自己保存,用于签名消息。公钥发给你想通信的人,用于验证信息是你发过来的,并且没有修改。一般只是用私钥进行签名,大家仍可以看到明文信息,作用只是确定完整性和可靠性 

    例如:
    String str = 123456;
    用私钥对str进行签名,会产生一串加密的信息。
    然后把明文和密文都发过去,对方用公钥进行验证这串信息是否被修改和确定是你发过来的,后面会有代码提到,具体如何验证的就需要进一步研究了。

    接下来就是证书,那证书为什么会起作用了?那就要看证书包含什么内容,一般我们所要用到的证书,我简称公钥证书,我了大致分为2部分。一部分是证书的相关信息,后面创建证书时会介绍到,第二部分就是公钥信息。此时就明白了,证书为什么会起作用,因为包含公钥。对方用私钥签名发送消息给你,而你获得对方的证书,里面有公钥,就可以进行验证了。

    接下又接触到CA的一些信息,CA:certificate Authority。不明白为什么要用到CA,CA到底要干什么了?
    举个例子就明白了
    A要发信息给B,A用私钥签名了消息发给B,B要验证消息是A发过来的,并且没有被修改过,就必须获得A的公钥去验证,此时B可以要求A通过某种途径把公钥发过来(以证书的形式)。
     这时问题来了,任何人都可以产生密钥对,B怎么知道获得的公钥是A的了。所以B就需要打电话跟A验证证书的指纹是否匹配,如果匹配就确定是A的公钥,指纹是创建证书时生成的,而且是唯一的,你可以用工具查看,后面会介绍到。大家会发现获得公钥每次都要与对方去验证,这是一个很麻烦的步骤,CA的作用就出现了,证书到CA那里走一趟,然后你获得证书就不需要在去验证了,但前提是你必须获得CA的证书,CA的证书获得就简单些,去官网弄,或者什么,但也需要验证证书的指纹,但毕竟只弄一次。
     那么CA对证书做了哪些操作了?简单的来说就是签名,后面在代码会看到的。CA会有一个根证书,也就是一个自签名的证书,一般创建的证书都是自签名证书。然后CA用根证书的私钥去签名你的证书,这时你的证书就有合法性,别人只需要用CA的公钥去验证你的证书就可以了,不需要再验证了。后面代码里面会提到CA做了什么。
 
    最后是密钥库,密钥库就是存放你的密钥一些信息,密钥库是以条目形式存放,条目英文名alias。在java代码中有个类KeyStore,查看API也可以了解密钥库。KeyStore里面存放3个实体,PrivateKeyEntry,SecretKeyEntry,TrustedCertificateEntry。一个条目就是条目名+实体。使用工具创建证书,实体是PrivateKeyEntry,其中包括私钥,和证书链,证书链第一个就是包含公钥的证书。你导入的CA公钥证书属于TrustedCertificateEntry。
    其中提到了证书链,证书链包含了一串证书,首先创建时就只包含一个自签名证书,在多数情况下,倒数第一个就是你的证书,倒数第二个就是证明你的证书,倒数第三个就是证明第二个的,以此类推。我是这样理解的,不知道顺序弄错没,证书一般都是以证书链形式传递。  

    首现创建证书:使用KeyTool和java程序 
一 KeyTool创建证书
     生成本地数字证书
     command:KeyTool -genkey -alias aliasName -keyStore storeName -Keyalg RSA -keysize 1024 -validity 3650 -dname "CN=country,ST=state,L=Locality,OU=OrganizationUnit,O=Organization"
     genkey会产生密钥对, alias条目名称,密钥库以条目的形式存放,keystore密钥库的名称,keyalg密钥算法,keysize密钥长度,密钥有1024和2048两个长度,dname证书的相关信息。创建成功后你可以在相应的目录下找到storeName这个文件,你可以用命令查看你所创建的证书。

     查看证书
     command:keytool -list -keystore storename
     可以看到认证指纹

     导出证书
     command:keytool -exportcert -alias aliasname -keystore storename -file cert.cer
     你可以在相应目录下找到cert.cer文件

二 Java创建证书

生成密钥对 (Java代码

<span style="font-family:Microsoft YaHei;font-size:14px;">   <span style="font-size:12px;"> KeyPairGenerator kg =  KeyPairGenerator.getInstance("RSA");    kg.initialize(1024, new SecureRandom());    KeyPair keyPair = kg.generateKeyPair();</span>   </span>


创建X509证书(Java代码

String name = "CN=country,ST=state,L=Locality,OU=OrganizationUnit,O=Organization";X509CertInfo x509CertInfo = new X509CertInfo();x509CertInfo.set(X509CertInfo.VERSION, new CertificateVersion(1));x509CertInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber((int) (System.currentTimeMillis() / 1000L)));X500Name x500Name = new X500Name(name);Signature signature = Signature.getInstance("MD5WithRSA"); X500Signer signer = new X500Signer(signature, x500Name);AlgorithmId algorithmId = signer.getAlgorithmId();x509CertInfo.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algorithmId));x509CertInfo.set(X509CertInfo.SUBJECT, new CertificateSubjectName(x500Name));x509CertInfo.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic()));CertificateValidity interval = new CertificateValidity(new Date(), new Date(System.currentTimeMillis() + 365000000000L));x509CertInfo.set(X509CertInfo.VALIDITY, interval);x509CertInfo.set(X509CertInfo.ISSUER, new CertificateIssuerName(signer.getSigner()));X509CertImpl x509CertImpl = new X509CertImpl(x509CertInfo);x509CertImpl.sign(keyPair.getPrivate(), "MD5WithRSA");


    这就创建了一个证书,大家可以从代码里面看到证书需要设置的信息,我解释一下
    Version:证书版本号
    SerialNumber:序列号
    algorithm_Id:签名算法
    subject:主体名
    key:公钥
    issuer:签发者
    我开始提到一般证书分二部分,这是我自己分的。Key作为一部分,其它的就是证书相关信息了。大家也在代码里面看到,signer创建时,使用的也是主体的信息X500Name,后面签名的时候也是用自己的privatekey签名,所以生成的证书就是自签名证书。CA如果要做操作,CA提取出自己的X500Name信息和PrivateKey,对这二项做操作,就变成了CA签名的证书了。

      证书创建完毕后,接下就是证书的功能签名了。

签名Java代码

  String str = "123456";  Signature sig = Signature.getInstance("MD5WithRSA");  sig.initSign(privateKey);  sig.update(str.getBytes());  byte[] bytes = sig.sign();  


验证(Java代码

  String str = "123456";  Signature sig = Signature.getInstance("MD5WithRSA");  sig.initVerify(publicKey);  sig.update(str.getBytes());  boolean flag = sig.verify(bytes);  


    这就是我前面所提到的例子,这里用java代码实现。应用到实际中,给本机弄一个唯一标识然后签名,写在http头部,然后发给对方,对方从头部获取然后验证。当然表中已经存在你的唯一标识和证书,应该是第一次发起通信时,CA公钥证书验证你的证书,然后保存你的唯一标识和证书。

    了解了证书之后,该是怎么应用了。
    证书存放:
    存放在表中:主要保存2个信息,证书和私钥。证书可以以X509Certificate这个类封装。
    存放在keystore中。

    读取证书信息:
    从表中就自己写SQL。
    从KeyStore中:(Java代码

  String storePass = "123456";  String aliasPass = "123456";  String aliasName = "aliasName";  String storeName = "C:\\Users\\liu\\storeName";  KeyStore ks = KeyStore.getInstance("JKS");  FileInputStream in = new FileInputStream(storeName);    ks.load(in, storePass.toCharArray());  Certificate cert = ks.getCertificate(aliasName);  PrivateKey pk = (PrivateKey) ks.getKey(aliasName, aliasPass.toCharArray());  PublicKey puk = cert.getPublicKey();

    有了证书之后,就需要把证书发给CA了。我们就需要发给CA一个证书签名请求,简称CSR(certificate signed request),签完名后返回证书签名响应,然后导入。
    生成CSR证书签名请求 。(Java代码

        X509Certificate x509Certificate;  //前面提到怎么获得        PrivateKey pk;                    //前面提到怎么获得        PKCS10 p10 = new PKCS10(x509Certificate.getPublicKey());        String algorithm = pk.getAlgorithm();        if ((algorithm.equalsIgnoreCase("DSA")) || (algorithm.equalsIgnoreCase("DSS"))) {            algorithm = "SHA1WithDSA";        } else if (algorithm.equalsIgnoreCase("RSA")) {            algorithm = "MD5WithRSA";        }        Signature sig = Signature.getInstance(algorithm);        sig.initSign(pk);        X500Name x500 = new X500Name(x509Certificate.getSubjectDN().toString());        X500Signer signer = new X500Signer(sig, x500);        p10.encodeAndSign(signer);  


用KeyTool:
    command: keytool -certreq -v -alias aliasName -keystore storeName -file codesigncsr.p10

    证书签名请求使用的是PKCS#10格式存放的
 
    CA签过名之后,导入签名的证书 。(Java代码

CertificateFactory cf = CertificateFactory.getInstance("X.509");FileInputStream in = new FileInputStream("C:\\Users\\liu\\csr.cer");certificate = cf.generateCertificate(in);

用KeyStore:
     command:keytool -import -file cer.cer -keystore storeName
注意的是,我导入的是证书,不是证书签名响应。步骤我猜是一样的,但没实际应用过。
   
 
    这是我从接触证书,然后自己查资料了解证书的一个过程,一个很简单的了解,写的很繁琐,可能也有很多理解错误的地方,希望大家多多指导。

    这是我主要借鉴证书资料的一些地址,他们写的很详细。有的介绍KeyTool使用很详细,有介绍加密解密的,可以从那里学习到SSLSocket,和对称,非对称加密解密,也算是证书的应用吧。本来想写到自己里面,可是发现基本照抄的,还是列出地址给大家。   

http://shellyli.iteye.com/blog/801638
http://lei-1021.iteye.com/blog/681691
http://lengjing.iteye.com/blog/1258892
http://chrui.iteye.com/blog/1018800

解压123456

原文地址:http://lujin55.iteye.com/blog/1436758#

 

 

 

 

 

 

 

 

 


0 0
原创粉丝点击