为了用java来使用数字证书,在网上google了一番,最后找到一个程序包jp0207bb.zip,下载的连接已经忘了。 里面有mscrypto.jar,mscryptofunctions.dll文件以及原代码,我跟着readme文件运行它自带的测试程序,结果总是出错,说我的证书的CDP域有错,我用的是cnca.net的试用型证书,可能有什么地方不兼容吧。实在没办法自己写了个测试的程序,不去验证证书的CDP域,照用就是,结果很正常。测试程序主要部分如下:
  列出所有证书:  MSCryptoFunctions MSF = new MSCryptoFunctions();  String[] aliases = MSF.MSgetAliases("My");  for(int i=0;i<aliases.length;i++)   {    //String alias = "{6014510D-21EF-4F49-8D93-0F19B821C0A0}";    String alias =aliases[i];    // get the cert for this alias    byte[] certblob = MSF.MSgetCert("My", alias);    CertificateFactory cf = CertificateFactory.getInstance("X.509");    ByteArrayInputStream input = new ByteArrayInputStream(certblob);    X509Certificate cert = (X509Certificate) cf.generateCertificate(input);    input.close();     System.out.println(cert.getSubjectDN().getName());   } CertificateFactory和X509Certificate所在的包是java.security.cert 
加密测试:     首先安装provider,代码如下:  import com.boyter.mscrypto.MSKeyMgrProvider;  import com.boyter.mscrypto.MSTrustMgrProvider;  import com.boyter.mscrypto.MSRSASignProvider;  import com.boyter.mscrypto.MSRSACipherProvider; 
 MSTrustMgrProvider.install();  MSKeyMgrProvider.install();  MSRSACipherProvider.install();  MSRSASignProvider.install();     取得加密用的证书,代码同列出证书的代码一样,到最后得到一个X509Certificate对象cert     初始化为ENCRYPT_MODE:      Cipher rc = Cipher.getInstance("RSA/ECB/PKCS1Padding","MSRSACipher");      rc.init( Cipher.ENCRYPT_MODE, cert.getPublicKey());     把要加密的文件(c:盘a.txt)读入到inputData数组:  byte[] inputData=new byte[(new Long((new File("c:\\a.txt")).length())).intValue()];  FileInputStream fis=new java.io.FileInputStream("c:\\a.txt");  fis.read(inputData);     对inputData加密,加密结果写入outputData:  byte[] outputData=null;  outputData = rc.doFinal(inputData);     把加密后的字节流写入另一个文件(c:盘a_enc.txt):  FileOutputStream fos=new FileOutputStream("c:\\a_enc.txt");  fos.write(outputData);  fos.close(); 运行后可以打开c:\a_enc.txt,看到内容变成了乱码,这些就是加密的结果。 
解密测试:     首先安装provider,然后取得证书,过程同加密测试。     初始化为DECRYPT_MODE:  Cipher rc = Cipher.getInstance("RSA/ECB/PKCS1Padding","MSRSACipher");  rc.init( Cipher.DECRYPT_MODE, cert.getPublicKey());     然后的做法根加密一样,把加密过的文件读入到inputData,然后运行rs.doFinal(inputData)得到解密后的字节流,再保存为另一个文件c:\\a_dec.txt; 运行后打开c:\a_dec.txt,内容应该和a.txt一样。 
 签名测试:  import java.security.Signature;  import javax.net.ssl.KeyManagerFactory;  import javax.net.ssl.X509KeyManager;  import java.security.PrivateKey;     安装provider,过程同加密测试。     获得私钥,注意获得私钥的方法和获得公钥方法不同,X509Certificate只有getPublicKey()方法,而没有getPrivateKey()方法,     要得到私钥必须通过X509KeyManager.getPrivateKey(alias)得到:  String[] aliases = MSF.MSgetAliases("My");  String alias =aliases[0];   //init  KeyManagerFactory kmf = KeyManagerFactory.getInstance("MSKMF");  kmf.init(null, null);  X509KeyManager xkm = (X509KeyManager)kmf.getKeyManagers()[0];  PrivateKey privkey = xkm.getPrivateKey(alias);     初始化:  Signature rsa = Signature.getInstance("MD5withRSA");  rsa.initSign(privkey);     把要签名的文件读到inputData,然后按如下过程签名:  rsa.update(inputData);  outputData = rsa.sign();     把outputData保存为文件c:\a_sign.txt,这个文件的内容就是签名。 
验证签名测试:     首先安装provider,然后取得证书X509Certificate对象cert,过程同加密测试。     初始化:  Signature rsa = Signature.getInstance("MD5withRSA");  rsa.initVerify(cert.getPublicKey());     把要验证签名的文件读到byte[]对象inputData,把签名读到另一个byte[]对象sign,然后按如下过程验证签名:  rsa.update(inputData);  rsa.verify(sign);     rsa.verify(sign)返回一个boolean对象,true表示验证通过,false表示验证不通过。     随便修改一下原文或者签名,再运行这段程序应该会返回false。
  完整的源代码如下: import com.boyter.mscrypto.MSCryptoFunctions; import java.io.ByteArrayInputStream; import java.security.cert.X509Certificate; import java.security.cert.CertificateFactory; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.File; import javax.crypto.Cipher; import java.security.Signature; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.X509KeyManager; import java.security.PrivateKey; import com.boyter.mscrypto.MSKeyMgrProvider; import com.boyter.mscrypto.MSTrustMgrProvider; import com.boyter.mscrypto.MSRSASignProvider; import com.boyter.mscrypto.MSRSACipherProvider; import com.boyter.mscrypto.MSValidCertificate; 
public class XxyTest {  static MSCryptoFunctions MSF = new MSCryptoFunctions();  public static void main(String[] args){   if(args[0].equals("list")){    try{     String[] aliases = MSF.MSgetAliases("My");     System.out.println("下面是windows证书库中所有证书:");     for(int i=0;i<aliases.length;i++)     {     //String alias = "{6014510D-21EF-4F49-8D93-0F19B821C0A0}";     String alias =aliases[i];     // get the cert for this alias     byte[] certblob = MSF.MSgetCert("My", alias);     CertificateFactory cf = CertificateFactory.getInstance("X.509");     ByteArrayInputStream input = new ByteArrayInputStream(certblob);     X509Certificate cert = (X509Certificate) cf.generateCertificate(input);     input.close();      System.out.println(cert.getSubjectDN().getName());     }    }catch(Exception e){     e.printStackTrace();    }   } 
  if(args[0].equals("encrypt")){    try{     System.out.println("加密测试,对c:\\a.txt加密,加密后生成c:\\a_enc.txt");     MSTrustMgrProvider.install();     MSKeyMgrProvider.install();     MSRSACipherProvider.install();     MSRSASignProvider.install();     //get public key     String[] aliases = MSF.MSgetAliases("My");     String alias =aliases[0];     byte[] certblob = MSF.MSgetCert("My", alias);     CertificateFactory cf = CertificateFactory.getInstance("X.509");     ByteArrayInputStream input = new ByteArrayInputStream(certblob);     X509Certificate cert = (X509Certificate) cf.generateCertificate(input);     input.close();      //init     Cipher rc = Cipher.getInstance("RSA/ECB/PKCS1Padding","MSRSACipher");     System.out.println("using provider: " + rc.getProvider().getName()); 
    rc.init( Cipher.ENCRYPT_MODE, cert.getPublicKey()); 
    String PaddingAlgorithm = "PKCS1";     byte[] outputData=null;     byte[] inputData=new byte[(new Long((new File("c:\\a.txt")).length())).intValue()];     FileInputStream fis=new java.io.FileInputStream("c:\\a.txt");     fis.read(inputData);     fis.close();     outputData = rc.doFinal(inputData);     FileOutputStream fos=new FileOutputStream("c:\\a_enc.txt");     fos.write(outputData);     fos.close();    }catch(Exception e){     e.printStackTrace();    }   } 
  if(args[0].equals("decrypt")){    try{     System.out.println("解密测试,对c:\\a_enc.txt解密,解密后生成c:\\a_dec.txt");     MSTrustMgrProvider.install();     MSKeyMgrProvider.install();     MSRSACipherProvider.install();     MSRSASignProvider.install();     //get public key     String[] aliases = MSF.MSgetAliases("My");     String alias =aliases[0];     byte[] certblob = MSF.MSgetCert("My", alias);     CertificateFactory cf = CertificateFactory.getInstance("X.509");     ByteArrayInputStream input = new ByteArrayInputStream(certblob);     X509Certificate cert = (X509Certificate) cf.generateCertificate(input);     input.close();      //init     Cipher rc = Cipher.getInstance("RSA/ECB/PKCS1Padding","MSRSACipher");     System.out.println("using provider: " + rc.getProvider().getName()); 
    rc.init( Cipher.DECRYPT_MODE, cert.getPublicKey()); 
    String PaddingAlgorithm = "PKCS1";     byte[] outputData=null;     byte[] inputData=new byte[(new Long((new File("c:\\a_enc.txt")).length())).intValue()];     FileInputStream fis=new java.io.FileInputStream("c:\\a_enc.txt");     fis.read(inputData);     fis.close();     outputData = rc.doFinal(inputData);     FileOutputStream fos=new FileOutputStream("c:\\a_dec.txt");     fos.write(outputData);     fos.close();    }catch(Exception e){     e.printStackTrace();    }   } 
  if(args[0].equals("sign")){    try{     System.out.println("签名测试,对c:\\a.txt签名,签名后生成c:\\a_sign.txt");     MSTrustMgrProvider.install();     MSKeyMgrProvider.install();     MSRSACipherProvider.install();     MSRSASignProvider.install();     //get public key     String[] aliases = MSF.MSgetAliases("My");     String alias =aliases[0];      //init     KeyManagerFactory kmf = KeyManagerFactory.getInstance("MSKMF");     kmf.init(null, null);     X509KeyManager xkm = (X509KeyManager)kmf.getKeyManagers()[0];     PrivateKey privkey = xkm.getPrivateKey(alias);     Signature rsa = Signature.getInstance("MD5withRSA");     rsa.initSign(privkey);          byte[] outputData=null;     byte[] inputData=new byte[(new Long((new File("c:\\a.txt")).length())).intValue()];     FileInputStream fis=new java.io.FileInputStream("c:\\a.txt");     fis.read(inputData);     fis.close();     rsa.update(inputData);     outputData = rsa.sign();     FileOutputStream fos=new FileOutputStream("c:\\a_sign.txt");     fos.write(outputData);     fos.close();    }catch(Exception e){     e.printStackTrace();    }   } 
  if(args[0].equals("verify")){    try{     System.out.println("验证签名测试,对c:\\a.txt验证签名,验证签名后生成c:\\a_verify.txt");     MSTrustMgrProvider.install();     MSKeyMgrProvider.install();     MSRSACipherProvider.install();     MSRSASignProvider.install();     //get public key     String[] aliases = MSF.MSgetAliases("My");     String alias =aliases[0];     byte[] certblob = MSF.MSgetCert("My", alias);     CertificateFactory cf = CertificateFactory.getInstance("X.509");     ByteArrayInputStream input = new ByteArrayInputStream(certblob);     X509Certificate cert = (X509Certificate) cf.generateCertificate(input);     input.close(); 
     Signature rsa = Signature.getInstance("MD5withRSA");     rsa.initVerify(cert.getPublicKey());               byte[] inputData=new byte[(new Long((new File("c:\\a.txt")).length())).intValue()];     FileInputStream fis=new java.io.FileInputStream("c:\\a.txt");     fis.read(inputData);     fis.close();     rsa.update(inputData);          byte[] sign=new byte[(new Long((new File("c:\\a_sign.txt")).length())).intValue()];     FileInputStream fis2=new java.io.FileInputStream("c:\\a_sign.txt");     fis2.read(sign); 
    if(rsa.verify(sign)){      System.out.println("验证通过");     }else{      System.out.println("验证不通过");     }     fis2.close();    }catch(Exception e){     e.printStackTrace();    }   }  } };  
 
  |