Terry.Li-彬

          虛其心,可解天下之問;專其心,可治天下之學;靜其心,可悟天下之理;恒其心,可成天下之業。

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            143 隨筆 :: 344 文章 :: 130 評論 :: 0 Trackbacks
          前幾次我已經基本上把如何做CA所需要的基礎知識講得差不多了,今天直接講如何用Java程序來實現一個CA應該就不是什么太困難的事情了.

              要做CA,第一步要準備好自己的證書和私鑰.私鑰如何從文件里面讀取出來前面已經講過了.從文件系統中讀出證書的代碼如下:

              CertificateFactory certCF = CertificateFactory.getInstance("X.509");
              X509Certificate caCert = certCF.generateCertificate(certBIS);

              這里cerBIS是一個InputStream類型的對象.例如一個標準的X509v3格式的證書文件所形成的輸入流.

              第二步就是從用戶那里獲取輸入,然后構造主體名稱結構DN,如何構造DN上次已經說過了,如何從用戶那里獲取輸入,這個不在本文討論范圍之內.

              下一步就是獲取用戶的公鑰,好和他所需要的證書對應起來.也有不少CA的做法就是在這里替用戶現場生成一對密鑰對,然后把公鑰放到證書中簽發給用戶.這個應該看實際需要選擇合適的方式.

              現在一切信息都已經準備好了,可以簽發證書了,下面的代碼說明了這個過程:

              //構造一個證書生成器對象

              X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();

              // 從CA的證書中獲取簽發者的主體名稱(DN)
              // 這里有一點小技巧,我們要把JCE中定義的
              // 用來表示DN的對象X500Principal轉化成在
              // BC Provider中的相應的對象X509Name
              // 先從CA的證書中讀取出CA的DN進行DER編碼
              DERInputStream dnStream =
                           new DERInputStream(
                new ByteArrayInputStream(
                 caCert.getSubjectX500Principal().
                  getEncoded()));
              // 馬上又從編碼后的字節流中讀取DER編碼對象
              DERConstructedSequence  dnSequence =
               (DERConstructedSequence)dnStream.readObject();
              // 利用讀取出來的DER編碼對象創建X509Name
              // 對象,并設置為證書生成器中的"簽發者DN"
              certGen.setIssuerDN(new X509Name(dnSequence));
              // 設置好證書生成器中的"接收方DN"
              certGen.setSubjectDN(subjectDN);
              // 設置好一些擴展字段,包括簽發者和
              // 接收者的公鑰標識
              certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
              createSubjectKeyId(keyToCertify));
              certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
              createAuthorityKeyId(caCert.getPublicKey()));
              // 設置證書的有效期和序列號
              certGen.setNotBefore(startDate);
              certGen.setNotAfter(endDate);
              certGen.setSerialNumber(serialNumber);
              // 設置簽名算法,本例中使用MD5hash后RSA
              // 簽名,并且設置好主體的公鑰
              certGen.setSignatureAlgorithm("MD5withRSA");
              certGen.setPublicKey(keyToCertify);

              // 如果以上一切都正常地話,就可以生成證書了
              X509Certificate cert = null;
              cert = certGen.generateX509Certificate(caPrivateKey);

              這里是上面用到的生成簽發者公鑰標識的函數: 

              protected AuthorityKeyIdentifier createAuthorityKeyId(PublicKey pubKey)
              {
              AuthorityKeyIdentifier authKeyId = null;

              try
              {
              ByteArrayInputStream bIn = new ByteArrayInputStream(pubKey.getEncoded());
              SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
                  (DERConstructedSequence)new DERInputStream(bIn).readObject());
              authKeyId = new AuthorityKeyIdentifier(info);
              }
              catch (IOException e)
              {
              System.err.println("Error generating SubjectKeyIdentifier:  " +
                  e.toString());
              System.exit(1);
              }

              return authKeyId;
              }

              生成主體公鑰標識的函數和上面的類似,把AuthorityKeyIdentifier替換成SubjectKeyIdentifier就可以了.

              這里要注意的是,CA的公鑰也是在一份證書里,這種證書的特點是簽發者DN和接收者DN一樣,也就是說,這種證書是CA自己給自己頒發的證書,也就是"自 簽名證書",它上面的公鑰是CA自身的公鑰,用來簽名的私鑰就是該公鑰對應的私鑰.一般每個CA都要有這么一份證書,除非該CA不是根CA,即它的權威性 不是由它自己證明,而是由它的上級CA證明.但是,最后總歸要有一個根CA,它為各個安全應用程序的用戶所信賴.

              到這里我們已經把CA最基本的功能如何用Java實現講完了,下一次講如何從PKCS#10格式證書請求文件中讀取出用戶信息,然后直接簽發公鑰.
          posted on 2008-02-13 22:13 禮物 閱讀(562) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。

          網站導航:
           
          主站蜘蛛池模板: 潜山县| 张家港市| 柘荣县| 乃东县| 井研县| 温州市| 娄底市| 昌平区| 木兰县| 赫章县| 武威市| 故城县| 新竹县| 肃宁县| 宁城县| 绵阳市| 当阳市| 分宜县| 图们市| 灌云县| 张北县| 大荔县| 芦山县| 章丘市| 新平| 陆河县| 湖北省| 广昌县| 普兰店市| 怀仁县| 梅州市| 朔州市| 疏附县| 东山县| 英吉沙县| 三明市| 宾阳县| 革吉县| 肃北| 嵊泗县| 青阳县|