初学certificate

来源:互联网 发布:linux iconv命令 编辑:程序博客网 时间:2024/06/04 18:02
出道半年多,感觉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代码  收藏代码
  1. KeyPairGenerator kg =  KeyPairGenerator.getInstance("RSA");  
  2. kg.initialize(1024new SecureRandom());  
  3. KeyPair keyPair = kg.generateKeyPair();  


    创建X509证书 
Java代码  收藏代码
  1. String name = "CN=country,ST=state,L=Locality,OU=OrganizationUnit,O=Organization";  
  2. X509CertInfo x509CertInfo = new X509CertInfo();  
  3. x509CertInfo.set(X509CertInfo.VERSION, new CertificateVersion(1));  
  4. x509CertInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber((int) (System.currentTimeMillis() / 1000L)));  
  5. X500Name x500Name = new X500Name(name);  
  6. Signature signature = Signature.getInstance("MD5WithRSA");   
  7. X500Signer signer = new X500Signer(signature, x500Name);  
  8. AlgorithmId algorithmId = signer.getAlgorithmId();  
  9. x509CertInfo.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algorithmId));  
  10. x509CertInfo.set(X509CertInfo.SUBJECT, new CertificateSubjectName(x500Name));  
  11. x509CertInfo.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic()));  
  12. CertificateValidity interval = new CertificateValidity(new Date(), new Date(System.currentTimeMillis() + 365000000000L));  
  13. x509CertInfo.set(X509CertInfo.VALIDITY, interval);  
  14. x509CertInfo.set(X509CertInfo.ISSUER, new CertificateIssuerName(signer.getSigner()));  
  15. X509CertImpl x509CertImpl = new X509CertImpl(x509CertInfo);  
  16. x509CertImpl.sign(keyPair.getPrivate(), "MD5WithRSA");  

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

  证书创建完毕后,接下就是证书的功能签名了。 
  签名 
 
Java代码  收藏代码
  1. String str = "123456";  
  2. Signature sig = Signature.getInstance("MD5WithRSA");  
  3. sig.initSign(privateKey);  
  4. sig.update(str.getBytes());  
  5. byte[] bytes = sig.sign();  

  验证 
 
Java代码  收藏代码
  1. String str = "123456";  
  2. Signature sig = Signature.getInstance("MD5WithRSA");  
  3. sig.initVerify(publicKey);  
  4. sig.update(str.getBytes());  
  5. boolean flag = sig.verify(bytes);  

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

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

  读取证书信息: 
  从表中就自己写SQL。 
  从KeyStore中: 
 
Java代码  收藏代码
  1. String storePass = "123456";  
  2. String aliasPass = "123456";  
  3. String aliasName = "aliasName";  
  4. String storeName = "C:\\Users\\liu\\storeName";  
  5. KeyStore ks = KeyStore.getInstance("JKS");  
  6. FileInputStream in = new FileInputStream(storeName);    
  7. ks.load(in, storePass.toCharArray());  
  8. Certificate cert = ks.getCertificate(aliasName);  
  9. PrivateKey pk = (PrivateKey) ks.getKey(aliasName, aliasPass.toCharArray());  
  10. PublicKey puk = cert.getPublicKey();  


  有了证书之后,就需要把证书发给CA了。我们就需要发给CA一个证书签名请求,简称CSR(certificate signed request),签完名后返回证书签名响应,然后导入。 
  生成CSR证书签名请求 
 
Java代码  收藏代码
  1. X509Certificate x509Certificate;  //前面提到怎么获得  
  2. PrivateKey pk;                    //前面提到怎么获得  
  3. PKCS10 p10 = new PKCS10(x509Certificate.getPublicKey());  
  4. String algorithm = pk.getAlgorithm();  
  5. if ((algorithm.equalsIgnoreCase("DSA")) || (algorithm.equalsIgnoreCase("DSS"))) {  
  6.     algorithm = "SHA1WithDSA";  
  7. else if (algorithm.equalsIgnoreCase("RSA")) {  
  8.     algorithm = "MD5WithRSA";  
  9. }  
  10. Signature sig = Signature.getInstance(algorithm);  
  11. sig.initSign(pk);  
  12. X500Name x500 = new X500Name(x509Certificate.getSubjectDN().toString());  
  13. X500Signer signer = new X500Signer(sig, x500);  
  14. p10.encodeAndSign(signer);  


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

证书签名请求使用的是PKCS#10格式存放的 
  
  CA签过名之后,导入签名的证书 
Java代码  收藏代码
  1. CertificateFactory cf = CertificateFactory.getInstance("X.509");  
  2. FileInputStream in = new FileInputStream("C:\\Users\\liu\\csr.cer");  
  3. certificate = cf.generateCertificate(in);  


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

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

[/url] 

转自:http://lujin55.iteye.com/blog/1436758

原创粉丝点击