通過我昨天的文章大家應(yīng)該已經(jīng)清楚了,用Java寫信息安全方面的程序需要做的準(zhǔn)備工作.好了,現(xiàn)在假設(shè)你已經(jīng)是一個對Java語言本身比較熟悉,能夠用Java寫一些程序的人,并且這些該下載的jar包已經(jīng)下載好了,可以正式開工了.
在所有的此類程序的開頭(無論是在類的構(gòu)造函數(shù)中也好,在初始化函數(shù)中也好),都要先來上這么一句:Security.addProvider(new
BouncyCastleProvider());將BouncyCaslte的Provider添加到系統(tǒng)中,這樣以后系統(tǒng)在運(yùn)行相關(guān)程序的時候調(diào)用的
就是這個Provider中的加密算法.
然后我們就可以開始開CA了.首先,作為一個CA要有自己的一對公鑰和私鑰,我們先要生成這么一對.使用KeyPairGenerator對象就可以了,
調(diào)用KeyPairGenerator.getInstance方法可以根據(jù)要生成的密鑰類型來產(chǎn)生一個合適的實(shí)例,例如常用的RSA,DSA等.然后調(diào)
用該對象的initialize方法和generateKeyPair方法就可以產(chǎn)生一個KeyPair對象了.然后調(diào)用KeyPair對象中的相應(yīng)方法
就可以獲取生成的密鑰對中的公鑰和私鑰了.
有了公鑰和私鑰對以后,下面的一個很現(xiàn)實(shí)問題就是如何把它們儲存起來.通常我們要對這些安全對象,如公鑰,私鑰,證書等先進(jìn)行編碼.編碼的目的是為了把結(jié)
構(gòu)復(fù)雜的安全對象變成字節(jié)流以便存儲和讀取,如DER編碼.另外,通常還把DER編碼后的字節(jié)流再次進(jìn)行base64編碼,以便使字節(jié)流中所有的字節(jié)都變
成可打印的字節(jié).
在Java語言中,這些安全對象基本上都有g(shù)etEncoded()方法.例如:
byte[] keyBytes = privateKey.getEncoded();
這樣就把一個私鑰進(jìn)行了DER編碼后的結(jié)果保存到一個byte數(shù)組中了.然后就可以把這個byte數(shù)組保存到任何介質(zhì)中.如果有必要的話,可以使用BC Provider中的Base64編碼解碼器類進(jìn)行編碼,就像這樣:
byte data[] = Base64.encode(keyBytes);
要從文件中讀取私鑰則應(yīng)該這樣:
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyData);
KeyFactory kfac = KeyFactory.getInstance("RSA");
privateKey = kfac.generatePrivate(spec);
這里說明一下,對RSA私鑰進(jìn)行編碼就會自動地按照PKCS8進(jìn)行.因此讀取的時候?qū)幋a的字節(jié)數(shù)組作為PKCS8EncodedKeySpec對象
的構(gòu)造函數(shù)的參數(shù)就可以生成一個該類型的對象.然后創(chuàng)建一個密鑰工廠對象就可以按照要求生成一個RSA私鑰了.很顯然這里的keyData應(yīng)該是和上面的
keyBytes內(nèi)容相同.
為了提高系統(tǒng)的安全性,通常私鑰在經(jīng)過DER編碼后,還會使用一個口令進(jìn)行加密,然后再儲存在文件系統(tǒng)中.在使用私鑰的時候,如果沒有正確的口令,是無法把私鑰還原出來的.
保存證書和保存私鑰類似.Certificate對象中也有一個getEncoded的方法.
這次就講這些.大家應(yīng)該可以把這些安全對象很熟練地從文件系統(tǒng)和內(nèi)存之間來回地折騰了吧.這對以后實(shí)現(xiàn)CA是很重要的.下次我會講一下證書中表示主體的方法:DN.