欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

初学certificate

程序员文章站 2022-07-14 15:04:31
...
  出道半年多,感觉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创建证书
    生成密钥对
   
    KeyPairGenerator kg =  KeyPairGenerator.getInstance("RSA");
    kg.initialize(1024, new SecureRandom());
    KeyPair keyPair = kg.generateKeyPair();
   


    创建X509证书
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签名的证书了。

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

  验证
 
  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中:
 
  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证书签名请求
 
        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签过名之后,导入签名的证书
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,和对称,非对称加密解密,也算是证书的应用吧。本来想写到自己里面,可是发现基本照抄的,还是列出地址给大家。   
[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]

解压123456