CRsa.java
上传用户:lior1029
上传日期:2013-05-07
资源大小:209k
文件大小:21k
源码类别:

CA认证

开发平台:

Java

  1. package org.infosecurity.cryptography;
  2. /**
  3.  * <p>Title: RSA算法的软件实现 </p>
  4.  * <p>Description: RSA算法的软件实现,功能包括:公钥加密私钥解密</p>
  5.  * <p>数字签名和签名验证,密钥对(公私钥)的生成,遵循PKCS标准</p>
  6.  * <p>Copyright: Copyright (c) 2003</p>
  7.  * <p>Company: 中信信息安全组织(CISO)</p>
  8.  * @author 张荣华
  9.  * @version 1.0.2003.0704
  10.  */
  11. import java.io.*;
  12. import java.math.*;
  13. import java.util.*;
  14. import java.security.SecureRandom;
  15. import org.bouncycastle.asn1.*;
  16. import org.bouncycastle.asn1.x509.*;
  17. import org.bouncycastle.util.encoders.*;
  18. public class CRsa extends Object implements Serializable {
  19.     // HASH算法的缺省摘要的信息
  20.     private final static byte[] SHA1_DIGEST_INFO = {
  21.         (byte)0x30, (byte)0x21, (byte)0x30, (byte)0x09, (byte)0x06,
  22.         (byte)0x05, (byte)0x2b, (byte)0x0e, (byte)0x03, (byte)0x02,
  23.         (byte)0x1a, (byte)0x05, (byte)0x00, (byte)0x04, (byte)0x14,
  24.         (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
  25.         (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
  26.         (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
  27.         (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
  28.     };
  29.     private final static byte[] MD5_DIGEST_INFO = {
  30.         (byte)0x30, (byte)0x20, (byte)0x30, (byte)0x0c, (byte)0x06,
  31.         (byte)0x08, (byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86,
  32.         (byte)0xf7, (byte)0x0d, (byte)0x02, (byte)0x05, (byte)0x05,
  33.         (byte)0x00, (byte)0x04, (byte)0x10, (byte)0x00, (byte)0x00,
  34.         (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
  35.         (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
  36.         (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
  37. };
  38.     private byte[] mTDefault=null;
  39.     private int    mLen=0;
  40.     //
  41.     private SecureRandom secureRd=new SecureRandom();
  42.     private static BigInteger ONE = BigInteger.valueOf(1);
  43.     private static BigInteger TWO = BigInteger.valueOf(2);
  44.     // ebase为17
  45.     private static BigInteger eBase = BigInteger.valueOf(0x11);
  46.     RSAPublicKey pukParam=null;
  47.     RSAPrivateKey pvkParam=null;
  48.     public CRsa() {
  49.     }
  50.     /**
  51.      *   设置公钥
  52.      */
  53.     public void setPublicKey(RSAPublicKey puk)
  54.     {
  55.         this.pukParam = puk;
  56.     }
  57.     /**
  58.      *   设置私钥
  59.      */
  60.     public void setPrivateKey(RSAPrivateKey pvk)
  61.     {
  62.         this.pvkParam = pvk;
  63.         this.pukParam = new RSAPublicKey(pvk.getModulus(),pvk.getExponent());
  64.     }
  65.     /**
  66.      *   公钥加密
  67.      */
  68.     public byte[] PublicKeyEncrypt(byte[] indata,int indatalen)
  69.             throws DataLengthException
  70.     {
  71.         int k=getInputBlockSize(true);
  72.         byte EncryptBlock[]=null;
  73.         // PS依据输入数据的长度>8
  74.         if (indatalen > getInputBlockSize(true)-10)
  75.         {
  76.             throw new DataLengthException("输入RSA加密的数据太长.n");
  77.         }
  78.         ByteArrayOutputStream baos=new ByteArrayOutputStream();
  79.         byte[] PS=new byte[(getOutputBlockSize(true)-indatalen-2)];
  80.         for(int i=0;i<PS.length;i++)
  81.         {
  82.             PS[i]=(byte)(secureRd.nextInt(255)+1);
  83.         }
  84.         try
  85.         {
  86.             baos.write((byte)0x02);
  87.             baos.write(PS);
  88.             baos.write((byte)0x00);
  89.             baos.write(indata);
  90.         }catch(IOException ioe){
  91.             ioe.printStackTrace();
  92.         }
  93.         EncryptBlock=baos.toByteArray();
  94.         BigInteger  input = new BigInteger(1, EncryptBlock);
  95.         byte[]      output=null;
  96.         output = input.modPow(pukParam.getExponent(), pukParam.getModulus()).toByteArray();
  97.         if (output[0] == 0 && output.length > getOutputBlockSize(true))//比输出长度长,截断
  98.         {
  99.             byte[]  tmp = new byte[output.length - 1];
  100.             System.arraycopy(output, 1, tmp, 0, tmp.length);
  101.             return tmp;
  102.         }
  103.         if (output.length < getOutputBlockSize(true))                 // 比输出长度短,增长
  104.         {
  105.             byte[]  tmp = new byte[getOutputBlockSize(true)];
  106.             System.arraycopy(output, 0, tmp, tmp.length - output.length, output.length);
  107.             return tmp;
  108.         }
  109.         return output;
  110.     }
  111.     /**
  112.      *   私钥解密
  113.      */
  114.     public byte[] PrivateKeyDecrypt(byte[] indata,int indatalen)
  115.             throws DataLengthException
  116.     {
  117.         int padLength=0;
  118.         if (indatalen > getInputBlockSize(false))
  119.         {
  120.             throw new DataLengthException("输入RSA解密的数据太长.");
  121.         }
  122.         byte[]      output=null;
  123.         BigInteger input=new BigInteger(1,indata);
  124.         output = input.modPow(pvkParam.getPrivateExponent(), pukParam.getModulus()).toByteArray();
  125.         if(output.length<10)
  126.             throw new DataLengthException("消息格式不对.");
  127.         if(output[0]!=(byte)0x02)
  128.         {
  129.             throw new DataLengthException("不是公钥操作的结果");
  130.         }
  131.         int start=0;
  132.         int outLen=output.length;
  133.         while(output[start]!=(byte)0x00)
  134.         {
  135.             start++;
  136.             if(start>=outLen)
  137.                 throw new DataLengthException("无效的填充数据!");
  138.         }
  139.         start++;          // 跳过0
  140.         byte tm[]=new byte[outLen-start];
  141.         try {
  142.             System.arraycopy(output,start,tm,0,tm.length);
  143.         }
  144.         catch (Exception ex) {
  145.             return null;
  146.         }
  147.         return tm;
  148.     }
  149.     /**
  150.      * 数字签名
  151.      * @param HashAlgorith 散列算法(5--md5 3--sha1)
  152.      * @param indata       输入数据
  153.      */
  154.     public byte[] signData(int HashAlgorithm,byte[] indata)
  155.             throws Exception
  156.     {
  157.         int indatalen=indata.length;
  158.         byte[] hashRes=null;
  159.         int blockLen=getInputBlockSize(true);
  160.         if(HashAlgorithm==5)
  161.             hashRes=new byte[16];
  162.         else if(HashAlgorithm==3)
  163.             hashRes=new byte[20];
  164.         else
  165.             throw new Exception("不支持的散列算法!");
  166.         if(indata==null||indata.length==0)
  167.             throw new Exception("输入数据为空");
  168.         if(HashAlgorithm==5)
  169.         {
  170.             // 生成摘要
  171.             mTDefault=new byte[MD5_DIGEST_INFO.length];
  172.             mLen=16;
  173.             System.arraycopy(MD5_DIGEST_INFO,0,mTDefault,0,mTDefault.length);
  174.             CMd5 md5=new CMd5();
  175.             for(int i=0;i<indatalen;i++)
  176.                 md5.update(indata[i]);
  177.             md5.doFinal(hashRes,0);
  178.             // 摘要编码
  179.             // 待编码的长度要比密钥的长度小1
  180.             byte inbyte[]=encode(hashRes,getOutputBlockSize(true)-1,16);
  181.             // 签名
  182.             byte[]      signData=null;
  183.             BigInteger input=new BigInteger(1,inbyte);
  184.             signData = input.modPow(pvkParam.getPrivateExponent(), pukParam.getModulus()).toByteArray();
  185.             // 如果是正数转成一个字节数组,我们将得到一个以0开头的结果
  186.             if (signData[0] == 0 && signData.length > getOutputBlockSize(true))//比输出长度长,截断
  187.             {
  188.                 byte[]  tmp = new byte[signData.length - 1];
  189.                 System.arraycopy(signData, 1, tmp, 0, tmp.length);
  190.                 return tmp;
  191.             }
  192.             if (signData.length < getOutputBlockSize(true))                 // 比输出长度短,增长
  193.             {
  194.                 byte[]  tmp = new byte[getOutputBlockSize(true)];
  195.                 System.arraycopy(signData, 0, tmp, tmp.length - signData.length, signData.length);
  196.                 return tmp;
  197.             }
  198.             return signData;
  199.         }
  200.         if(HashAlgorithm==3)
  201.         {
  202.             mTDefault=new byte[SHA1_DIGEST_INFO.length];
  203.             mLen=20;
  204.             System.arraycopy(SHA1_DIGEST_INFO,0,mTDefault,0,mTDefault.length);
  205.             CSha1 sha1=new CSha1();
  206.             for(int i=0;i<indatalen;i++)
  207.                 sha1.update(indata[i]);
  208.             sha1.doFinal(hashRes,0);
  209.             // 摘要编码
  210.              byte inbyte[]=encode(hashRes,getOutputBlockSize(true)-1,20);
  211.              // 签名
  212.              byte[]      signData=null;
  213.              BigInteger input=new BigInteger(1,inbyte);
  214.              signData = input.modPow(pvkParam.getPrivateExponent(), pukParam.getModulus()).toByteArray();
  215.              if (signData[0] == 0 && signData.length > getOutputBlockSize(true))//比输出长度长,截断
  216.              {
  217.                  byte[]  tmp = new byte[signData.length - 1];
  218.                  System.arraycopy(signData, 1, tmp, 0, tmp.length);
  219.                  return tmp;
  220.              }
  221.              if (signData.length < getOutputBlockSize(true))                 // 比输出长度短,增长
  222.              {
  223.                  byte[]  tmp = new byte[getOutputBlockSize(true)];
  224.                  System.arraycopy(signData, 0, tmp, tmp.length - signData.length, signData.length);
  225.                  return tmp;
  226.              }
  227.              return signData;
  228.         }
  229.         return null;
  230.     }
  231.     /**
  232.      *   验证数字签名
  233.      */
  234.     public int verifySignData(byte[] indata,byte[] plainData)throws Exception
  235.     {
  236.         try {
  237.             if(indata.length>getInputBlockSize(false))
  238.                 throw new Exception("签名的输入长度过长!");
  239.             BigInteger input=new BigInteger(1,indata);
  240.             byte[] out = input.modPow(pukParam.getExponent(), pukParam.getModulus()).toByteArray();
  241.             byte[] bEncodedHash=decode(out);
  242.             ByteArrayInputStream bIn=null;
  243.             bIn = new ByteArrayInputStream(bEncodedHash);
  244.             DERInputStream dIn = new DERInputStream(bIn);
  245.             ASN1Sequence   seq = (ASN1Sequence)dIn.readObject();
  246.             if(seq.size()==2)
  247.             {
  248.                 DigestInfo digestInf=DigestInfo.getInstance(seq);
  249.                 AlgorithmIdentifier aID=digestInf.getAlgorithmId();
  250.                 if(aID.getObjectId().getId().equals("1.2.840.113549.2.5"))//MD5
  251.                 {
  252.                     // 生成摘要
  253.                     int plainDataLength=0;
  254.                     plainDataLength=plainData.length;
  255.                     byte[] plainHash=new byte[16];
  256.                     CMd5 md5=new CMd5();
  257.                     for(int i=0;i<plainDataLength;i++)
  258.                         md5.update(plainData[i]);
  259.                     md5.doFinal(plainHash,0);
  260.                     byte[] digest=digestInf.getDigest();
  261.                    for(int i=0;i<md5.getDigestSize();i++)
  262.                    {
  263.                        //System.out.println("result="+digest[i]+"plain="+plainHash[i]);
  264.                        if(digest[i]==plainHash[i])
  265.                        {
  266.                            //调试输出语句
  267.                            continue;
  268.                        }
  269.                        else
  270.                            return 0;
  271.                    }
  272.                    return 1;
  273.                 }
  274.                 else if(aID.getObjectId().getId().equals("1.3.14.3.2.26"))
  275.                 {
  276.                     // 生成摘要
  277.                     int plainDataLength=0;
  278.                     plainDataLength=plainData.length;
  279.                     byte[] plainHash=new byte[20];
  280.                     CSha1 sha1=new CSha1();
  281.                     for(int i=0;i<plainDataLength;i++)
  282.                         sha1.update(plainData[i]);
  283.                     sha1.doFinal(plainHash,0);
  284.                     byte[] digest=digestInf.getDigest();
  285.                    for(int i=0;i<sha1.getDigestSize();i++)
  286.                    {
  287.                        if(digest[i]==plainHash[i])
  288.                            continue;
  289.                        else
  290.                            return 0;
  291.                    }
  292.                    return 1;
  293.                 }
  294.                 else
  295.                 {
  296.                    // 目前不支持该算法
  297.                     return 0;
  298.                 }
  299.             }
  300.             else
  301.                 return 0;
  302.         }
  303.         catch (Exception e) {
  304.             e.printStackTrace();
  305.             return 0;
  306.         }
  307.     }
  308.     // 最大输入长度
  309.     private int getInputBlockSize(boolean forEncryption)
  310.     {
  311.         int     bitSize = pukParam.getModulus().bitLength();
  312.         if (forEncryption)
  313.         {
  314.             return (bitSize + 7) / 8 - 1;
  315.         }
  316.         else
  317.         {
  318.             return (bitSize + 7) / 8;
  319.         }
  320.     }
  321.     // 最大的输出长度
  322.     private int getOutputBlockSize(boolean forEncryption)
  323.     {
  324.         int     bitSize =
  325.         pukParam.getModulus().bitLength();
  326.         if (forEncryption)
  327.         {
  328.             return (bitSize + 7) / 8;
  329.         }
  330.         else
  331.         {
  332.             return (bitSize + 7) / 8 - 1;
  333.         }
  334.     }
  335.     // 密钥对的生成
  336.     public int generateKeyPair(int length)
  337.     {
  338.         BigInteger    p, q, n, d, e, pSub1, qSub1, phi;
  339.         BigInteger    dP, dQ, qInv;
  340.         int pbitlength = (length + 1) / 2;
  341.         int qbitlength = (length- pbitlength);
  342.         //e在标准中推荐使用3或65537
  343.         e=new BigInteger("65537",10);
  344.         //生成素数p,并且使p-1与e互素
  345.         for (;;)
  346.         {
  347.             p = new BigInteger(pbitlength, 50,new SecureRandom());
  348.             if (e.gcd(p.subtract(ONE)).equals(ONE)) break;
  349.         }
  350.         for (;;)
  351.         {
  352.             //生成素数q,并且使q-1与e互素,与p不相等
  353.             for (;;)
  354.             {
  355.                 q = new BigInteger(qbitlength,50,new SecureRandom());
  356.                 if (e.gcd(q.subtract(ONE)).equals(ONE) && !p.equals(q)) break;
  357.             }
  358.             //模数n=p*q
  359.             n = p.multiply(q);
  360.             if (n.bitLength() == length) break;
  361.             p = p.max(q);
  362.         }
  363.         //pSub1=p-1
  364.         //qSub1=q-1
  365.         pSub1 = p.subtract(ONE);
  366.         qSub1 = q.subtract(ONE);
  367.         //计算(p-1)*(q-1)
  368.         phi = pSub1.multiply(qSub1);
  369.         //求私钥指数d:  按公式d*e=n mod (p-1)(q-1)
  370.         d = e.modInverse(phi);
  371.         //应用中国剩余定理
  372.         //求CRT指数:dQ=d mod (q-1)
  373.         //求CRT指数:dP=d mod (p-1)
  374.         dP = d.remainder(pSub1);
  375.         dQ = d.remainder(qSub1);
  376.         //1/q mod p0
  377.         qInv = q.modInverse(p);
  378.         pukParam=new RSAPublicKey(n, e);
  379.         pvkParam=new RSAPrivateKey(n, e, d, p, q, dP, dQ, qInv);
  380.         return 1;
  381.     }
  382.     public byte[] encode(byte[] H, int outLen,int mHLen)
  383.         throws Exception
  384.     {
  385.         if (outLen < mTDefault.length + 10) {
  386.             throw new Exception("encoding too short");
  387.         }
  388.         byte[] T = new byte[mTDefault.length];
  389.         System.arraycopy(mTDefault,0,T,0,T.length);
  390.         System.arraycopy(H,0,T,T.length - mHLen,mHLen);
  391.         byte[] PS = new byte[outLen - T.length - 2];
  392.         for (int i = 0; i < PS.length; i++) {
  393.             PS[i] = (byte)0xFF;
  394.         }
  395.         // Create the output block, 01 || PS || 00 || T.
  396.         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  397.         try {
  398.             baos.write((byte)0x01);
  399.             baos.write(PS);
  400.             baos.write((byte)0x00);
  401.             baos.write(T);
  402.         } catch (IOException ioe) {
  403.             // This should never happen
  404.             ioe.printStackTrace();
  405.         }
  406.         byte[] EM = baos.toByteArray();
  407.         return EM;
  408. }
  409.     public byte[] decode(byte[] indata) throws Exception
  410.     {
  411.         if(indata.length<34)
  412.             throw new Exception("消息格式不对.");
  413.         if(indata[0]!=(byte)0x01)
  414.         {
  415.             throw new Exception("不是签名的结果");
  416.         }
  417.         int start=0;
  418.         int outLen=indata.length;
  419.         while(indata[start]!=(byte)0x00)
  420.         {
  421.             start++;
  422.             if(start>=outLen)
  423.                 throw new Exception("无效的填充数据!");
  424.         }
  425.         start++;          // 跳过0
  426.         byte tm[]=new byte[outLen-start];
  427.         try {
  428.             System.arraycopy(indata,start,tm,0,tm.length);
  429.         }
  430.         catch (Exception ex) {
  431.             return null;
  432.         }
  433.         return tm;
  434.     }
  435.     public RSAPublicKey getPublicKey()
  436.     {
  437.         return pukParam;
  438.     }
  439.     public RSAPrivateKey getPrivateKey()
  440.     {
  441.         return pvkParam;
  442.     }
  443.     /**
  444.      * 将公钥读入
  445.      * @author 张荣华
  446.      */
  447.     public RSAPublicKey readPuk(String strPukFileName)
  448.             throws IOException
  449.     {
  450.         FileInputStream fis = new FileInputStream(strPukFileName);
  451.         int fLength         = fis.available();
  452.         byte[] bytePuk          = new byte[fLength];
  453.         fis.read(bytePuk,0,fLength);
  454.         fis.close();
  455.         ByteArrayInputStream bIn = new ByteArrayInputStream(bytePuk);
  456.         DERInputStream dIn = new DERInputStream(bIn);
  457.         ASN1Sequence      seq = (ASN1Sequence)dIn.readObject();
  458.         if(seq.size()==2)
  459.         {
  460.             DERInteger n = (DERInteger)seq.getObjectAt(0);
  461.             DERInteger e = (DERInteger)seq.getObjectAt(1);
  462.             return new RSAPublicKey(n.getValue(),e.getValue());
  463.         }
  464.         return null;
  465.     }
  466.     /**
  467.      * 将公钥写入到文件(DER)编码
  468.      * @author 张荣华
  469.      */
  470.     public int writePuk(RSAPublicKey puk,String strPukFileName)
  471.             throws IOException
  472.     {
  473.         ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
  474.         DEROutputStream         dOut = new DEROutputStream(bOut);
  475.         dOut.writeObject(puk.getDERObject());
  476.         byte[] m_bPuk=bOut.toByteArray();
  477.         dOut.close();
  478.         FileOutputStream fos = new FileOutputStream(strPukFileName);
  479.         fos.write(m_bPuk);
  480.         fos.flush();
  481.         fos.close();
  482.         return 1;
  483.     }
  484.     /**
  485.      * 将私钥写入到文件(DER编码)
  486.      * @author 张荣华
  487.      */
  488.     public int writePvk(RSAPrivateKey pvk,String strPvkFileName)
  489.             throws IOException
  490.     {
  491.         ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
  492.         DEROutputStream         dOut = new DEROutputStream(bOut);
  493.         dOut.writeObject(pvk.getDERObject());
  494.         byte[] m_bPvk=bOut.toByteArray();
  495.         dOut.close();
  496.         FileOutputStream fos = new FileOutputStream(strPvkFileName);
  497.         fos.write(m_bPvk);
  498.         fos.flush();
  499.         fos.close();
  500.         return 1;
  501.     }
  502.     /**
  503.      * 从文件读入公钥
  504.      * @author 张荣华
  505.      */
  506.     public RSAPrivateKey readPvk(String strPvkFileName)
  507.             throws IOException
  508.     {
  509.         FileInputStream fis = new FileInputStream(strPvkFileName);
  510.         int fLength         = fis.available();
  511.         byte[] bytePvk          = new byte[fLength];
  512.         fis.read(bytePvk,0,fLength);
  513.         fis.close();
  514.         ByteArrayInputStream bIn = new ByteArrayInputStream(bytePvk);
  515.         DERInputStream dIn = new DERInputStream(bIn);
  516.         ASN1Sequence      seq = (ASN1Sequence)dIn.readObject();
  517.         if(seq.size()==9)
  518.         {
  519.             DERInteger n = (DERInteger)seq.getObjectAt(1);
  520.             DERInteger e = (DERInteger)seq.getObjectAt(2);
  521.             DERInteger d = (DERInteger)seq.getObjectAt(3);
  522.             DERInteger p = (DERInteger)seq.getObjectAt(4);
  523.             DERInteger q = (DERInteger)seq.getObjectAt(5);
  524.             DERInteger dp = (DERInteger)seq.getObjectAt(6);
  525.             DERInteger dq = (DERInteger)seq.getObjectAt(7);
  526.             DERInteger qInv = (DERInteger)seq.getObjectAt(8);
  527.             return new RSAPrivateKey(
  528.                     n.getValue(),e.getValue(),d.getValue(),
  529.                     p.getValue(),q.getValue(),dp.getValue(),
  530.                     dq.getValue(),qInv.getValue());
  531.         }
  532.         return null;
  533.     }
  534.     /**
  535.      * 以下是RSA算法的软件实现测试程序
  536.      * @author 张荣华
  537.      */
  538.     public static void main(String[] args) {
  539.         CRsa rsa= new CRsa();
  540.         // 密钥生成测试
  541.         // 密钥长度支持512 768 1024 2048 4096 再长也支持,但怕你的机器受不了
  542.         System.out.println("=====================密钥生成测试======================");
  543.         rsa.generateKeyPair(512);
  544.         //rsa.savePukToFile("E:\JavaProj\temp\puk.key");
  545.         //rsa.savePvkToFile("E:\JavaProj\temp\pvk.key");
  546.         try {
  547.             rsa.writePuk(rsa.getPublicKey(),"E:\JavaProj\temp\puk.key");
  548.             rsa.writePvk(rsa.getPrivateKey(),"E:\JavaProj\temp\pvk.key");
  549. //            rsa.readPuk("E:\JavaProj\temp\puk.key");
  550. //            rsa.readPvk("E:\JavaProj\temp\pvk.key");
  551.         }
  552.         catch (IOException ex) {
  553.         }
  554.         System.out.println(rsa.getPublicKey().getModulus().toString(16));
  555.         // 公钥加密私钥解密测试
  556.         System.out.println("==================公钥加密私钥解密测试==================");
  557.         String str="你好,张荣华!";
  558.         byte[] indata=str.getBytes();
  559.         int indatalen=indata.length;
  560.         byte[] cipherData=null;
  561.         byte[] plainData=null;
  562.         try {
  563.             cipherData=rsa.PublicKeyEncrypt(indata,indatalen);
  564.         }
  565.         catch (Exception ex) {
  566.             //ex.printStackTrace();
  567.         }
  568.         try {
  569.             plainData=rsa.PrivateKeyDecrypt(cipherData,cipherData.length);
  570.         }
  571.         catch (Exception ex) {
  572.             //ex.printStackTrace();
  573.         }
  574.         System.out.println("解出的明文:t"+new String(plainData));
  575.         System.out.println("长度(字节)=t"+plainData.length);
  576.         // 数字签名及签名验证测试
  577.         System.out.println("==================数字签名及签名验证测试==================");
  578.         String strSign="这是一个签名测试!";
  579.         byte[] signRes=null;
  580.         try {
  581.             // MD5WithRSA
  582.             signRes=rsa.signData(5,strSign.getBytes());
  583.         }
  584.         catch (Exception ex) {
  585.             ex.printStackTrace();
  586.         }
  587.         try {
  588.             int success=rsa.verifySignData(signRes,strSign.getBytes());
  589.             if(success==1)
  590.                 System.out.println("签名验证成功!");
  591.             else
  592.                 System.out.println("签名验证失败!");
  593.         }
  594.         catch (Exception ex) {
  595.         }
  596.     }
  597. }