下面产生一个自签证书。安装完J2SDK(这里用的是J2SDK1.4)后,在J2SDK安装目录的bin目录下,有一个keytool的可执行程序。利用keytool产生自签证书的步骤如下: 第一步,用-genkey命令选项,产生公私密钥对。在控制台界面输入:keytool -genkey -alias testkeypair -keyalg RSA -keysize 1024 -sigalg MD5withRSA。这里的-alias表示使用这对公私密钥产生新的keystore入口的别名(keystore是用来存放管理密钥对和证书链的,缺省位置是在使用者主目录下,以.keystore为名的隐藏文件,当然也可指定某个路径存放.keystore文件);-keyalg是产生公私钥对所用的算法,这里是RSA;-keysize定义密钥的长度;-sigalg是签名算法,选择MD5withRSA,即用RSA签名,然后用MD5哈希算法摘要。接下来,系统会提示进行一些输入: 输入keystore密码:  abc123
            您的名字与姓氏是什么?
            [Unknown]:  Li
            您的组织单位名称是什么?
            [Unknown]:  InfosecLab
            您的组织名称是什么?
            [Unknown]:  InfosecLab Group
            您所在的城市或区域名称是什么?
            [Unknown]:  Beijing
            您所在的州或省份名称是什么?
            [Unknown]:  Beijing
            该单位的两字母国家代码是什么
            [Unknown]:  CN
            CN=Li, OU=InfosecLab, O=InfosecLab Group, L=Beijing, ST=Beijing, C=CN 正确吗?
            [否]:  y
            输入<testkeypair>的主密码 (如果和 keystore 密码相同,按回车):
 
第二步,产生自签证书,输入以下命令: keytool -selfcert -alias testkeypair -dname "CN=Li, OU=InfosecLab, O=InfosecLab
            Group, L=Beijing, ST=Beijing, C=CN"
            输入keystore密码:  abc123
 
第三步,导出自签证书,由上面两步产生的证书,已经存放在以“testkeypair”为别名的keystore入口了,如果使用其文件,必须导出证书。输入: keytool -export -rfc -alias testkeypair -file mycert.crt
            输入keystore密码:  abc123
            保存在文件中的认证 <mycert.crt>
 
这样,就得到了一个自签的证书mycert.crt。注意,选项rfc是把证书输出为RFC1421定义的、用Base64最终编码的格式。 

解决方案 »

  1.   

    加密函数写成: public static void crypt(byte[] cipherText,String outFileName){
                try{
                DESKeySpec desKeySpec = new DESKeySpec(desKeyData);
                SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
                SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
                Cipher cdes = Cipher.getInstance("DES");
                cdes.init(Cipher.ENCRYPT_MODE, secretKey);
                byte[] ct = cdes.doFinal(cipherText);
                try{
                FileOutputStream out=new FileOutputStream(outFileName);
                out.write(ct);
                out.close();
                }catch(IOException e){
                e.printStackTrace();
                }
                }catch (Exception e){
                e.printStackTrace();
                }
                }
     
    其中ct就是加密后的内容,outFileName保存加密后文件的文件名。把cdes.init(Cipher.ENCRYPT_MODE, secretKey)换成cdes.init(Cipher.DECRYPT_MODE, secretKey)就是解密文件了。 文件加密后就要对文件签名,保证A发送到B的文件不可伪造。下面是用存放在.keystore中的私钥进行签名的函数,签名使用的摘要算法是MD5。其中sigText是被签名内容的输入数组,outFileName是保存签名后输出文件的名称,KeyPassword是读取Keystore使用的密码,KeyStorePath是存放.keystore文件的路径,函数代码如下: public static void sig(byte[] sigText, String outFileName,String
                KeyPassword,String KeyStorePath){
                char[] kpass;
                int i;
                try{
                KeyStore ks = KeyStore.getInstance("JKS");
                FileInputStream ksfis = new FileInputStream(KeyStorePath);
                BufferedInputStream ksbufin = new BufferedInputStream(ksfis);
                kpass=new char[KeyPassword.length()];
                for(i=0;i<KeyPassword.length();i++)
                kpass[i]=KeyPassword.charAt(i);
                ks.load(ksbufin, kpass);
                PrivateKey priv = (PrivateKey) ks.getKey(KeystoreAlias,kpass );
                Signature rsa=Signature.getInstance("MD5withRSA");
                rsa.initSign(priv);
                rsa.update(sigText);
                byte[] sig=rsa.sign();
                System.out.println("sig is done");
                try{
                FileOutputStream out=new FileOutputStream(outFileName);
                out.write(sig);
                out.close();
                }catch(IOException e){
                e.printStackTrace();
                }
                }catch(Exception e){
                e.printStackTrace();
                }
                }
     
    验证签名需要存放签名文件和被签名的文件以及证书,其中,updateData存放被签名文件的内容,sigedText存放得到的签名内容,CertName是证书名。验证签名代码如下: public static void veriSig(byte[] updateData, byte[] sigedText){
                try{
                CertificateFactory
                certificatefactory=CertificateFactory.getInstance("X.509");
                FileInputStream fin=new FileInputStream(CertName);
                X509Certificate
                certificate=(X509Certificate)certificatefactory.generateCertificate(fin);
                PublicKey pub = certificate.getPublicKey();
                Signature rsa=Signature.getInstance("MD5withRSA");
                rsa.initVerify(pub);
                rsa.update(updateData);
                boolean verifies=rsa.verify(sigedText);
                System.out.println("verified "+verifies);
                if(verifies){
                System.out.println("Verify is done!");
                }else{
                System.out.println("verify is not successful");
                }
                }catch(Exception e){
                e.printStackTrace();
                }
                }
     
    可以用keytool产生两个自签的签名证书,或者到某个CA去申请两个证书。用Java编写加密和验证程序,上述例子只是一个非常简单的证书应用,实际协议对证书的使用(比如SSL)要比这个复杂多了。