⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crsa.java

📁 说明: 1、里面有什么: 1.1、org.bouncycastle.*下的所有软件是bouncycastle组织开发的软件包 1.2、org.infosecurity.*下的软件包括
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            e.printStackTrace();
            return 0;
        }
    }
    // 最大输入长度
    private int getInputBlockSize(boolean forEncryption)
    {
        int     bitSize = pukParam.getModulus().bitLength();

        if (forEncryption)
        {
            return (bitSize + 7) / 8 - 1;
        }
        else
        {
            return (bitSize + 7) / 8;
        }
    }
    // 最大的输出长度
    private int getOutputBlockSize(boolean forEncryption)
    {
        int     bitSize =
        pukParam.getModulus().bitLength();
        if (forEncryption)
        {
            return (bitSize + 7) / 8;
        }
        else
        {
            return (bitSize + 7) / 8 - 1;
        }
    }
    // 密钥对的生成
    public int generateKeyPair(int length)
    {
        BigInteger    p, q, n, d, e, pSub1, qSub1, phi;
        BigInteger    dP, dQ, qInv;

        int pbitlength = (length + 1) / 2;
        int qbitlength = (length- pbitlength);
        //e在标准中推荐使用3或65537
        e=new BigInteger("65537",10);

        //生成素数p,并且使p-1与e互素
        for (;;)
        {
            p = new BigInteger(pbitlength, 50,new SecureRandom());
            if (e.gcd(p.subtract(ONE)).equals(ONE)) break;
        }

        for (;;)
        {
            //生成素数q,并且使q-1与e互素,与p不相等
            for (;;)
            {
                q = new BigInteger(qbitlength,50,new SecureRandom());
                if (e.gcd(q.subtract(ONE)).equals(ONE) && !p.equals(q)) break;
            }

            //模数n=p*q
            n = p.multiply(q);

            if (n.bitLength() == length) break;
            p = p.max(q);
        }
        //pSub1=p-1
        //qSub1=q-1
        pSub1 = p.subtract(ONE);
        qSub1 = q.subtract(ONE);
        //计算(p-1)*(q-1)
        phi = pSub1.multiply(qSub1);

        //求私钥指数d:  按公式d*e=n mod (p-1)(q-1)
        d = e.modInverse(phi);

        //应用中国剩余定理

        //求CRT指数:dQ=d mod (q-1)
        //求CRT指数:dP=d mod (p-1)
        dP = d.remainder(pSub1);
        dQ = d.remainder(qSub1);
        //1/q mod p0
        qInv = q.modInverse(p);
        pukParam=new RSAPublicKey(n, e);
        pvkParam=new RSAPrivateKey(n, e, d, p, q, dP, dQ, qInv);
        return 1;
    }
    public byte[] encode(byte[] H, int outLen,int mHLen)
        throws Exception
    {
        if (outLen < mTDefault.length + 10) {
            throw new Exception("encoding too short");
        }
        byte[] T = new byte[mTDefault.length];
        System.arraycopy(mTDefault,0,T,0,T.length);

        System.arraycopy(H,0,T,T.length - mHLen,mHLen);
        byte[] PS = new byte[outLen - T.length - 2];
        for (int i = 0; i < PS.length; i++) {
            PS[i] = (byte)0xFF;
        }
        // Create the output block, 01 || PS || 00 || T.
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            baos.write((byte)0x01);
            baos.write(PS);
            baos.write((byte)0x00);
            baos.write(T);
        } catch (IOException ioe) {
            // This should never happen
            ioe.printStackTrace();
        }

        byte[] EM = baos.toByteArray();
        return EM;
	}
    public byte[] decode(byte[] indata) throws Exception
    {
        if(indata.length<34)
            throw new Exception("消息格式不对.");
        if(indata[0]!=(byte)0x01)
        {
            throw new Exception("不是签名的结果");
        }
        int start=0;
        int outLen=indata.length;
        while(indata[start]!=(byte)0x00)
        {
            start++;
            if(start>=outLen)
                throw new Exception("无效的填充数据!");
        }
        start++;          // 跳过0
        byte tm[]=new byte[outLen-start];
        try {
            System.arraycopy(indata,start,tm,0,tm.length);
        }
        catch (Exception ex) {
            return null;
        }
        return tm;
    }
    public RSAPublicKey getPublicKey()
    {
        return pukParam;
    }
    public RSAPrivateKey getPrivateKey()
    {
        return pvkParam;
    }
    /**
     * 将公钥读入
     * @author 张荣华
     */
    public RSAPublicKey readPuk(String strPukFileName)
            throws IOException
    {
        FileInputStream fis = new FileInputStream(strPukFileName);
        int fLength         = fis.available();
        byte[] bytePuk          = new byte[fLength];
        fis.read(bytePuk,0,fLength);
        fis.close();
        ByteArrayInputStream bIn = new ByteArrayInputStream(bytePuk);
        DERInputStream dIn = new DERInputStream(bIn);
        ASN1Sequence      seq = (ASN1Sequence)dIn.readObject();
        if(seq.size()==2)
        {
            DERInteger n = (DERInteger)seq.getObjectAt(0);
            DERInteger e = (DERInteger)seq.getObjectAt(1);
            return new RSAPublicKey(n.getValue(),e.getValue());
        }
        return null;
    }
    /**
     * 将公钥写入到文件(DER)编码
     * @author 张荣华
     */
    public int writePuk(RSAPublicKey puk,String strPukFileName)
            throws IOException
    {
        ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
        DEROutputStream         dOut = new DEROutputStream(bOut);
        dOut.writeObject(puk.getDERObject());
        byte[] m_bPuk=bOut.toByteArray();
        dOut.close();
        FileOutputStream fos = new FileOutputStream(strPukFileName);
        fos.write(m_bPuk);
        fos.flush();
        fos.close();
        return 1;
    }
    /**
     * 将私钥写入到文件(DER编码)
     * @author 张荣华
     */
    public int writePvk(RSAPrivateKey pvk,String strPvkFileName)
            throws IOException
    {
        ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
        DEROutputStream         dOut = new DEROutputStream(bOut);
        dOut.writeObject(pvk.getDERObject());
        byte[] m_bPvk=bOut.toByteArray();
        dOut.close();
        FileOutputStream fos = new FileOutputStream(strPvkFileName);
        fos.write(m_bPvk);
        fos.flush();
        fos.close();
        return 1;
    }
    /**
     * 从文件读入公钥
     * @author 张荣华
     */
    public RSAPrivateKey readPvk(String strPvkFileName)
            throws IOException
    {
        FileInputStream fis = new FileInputStream(strPvkFileName);
        int fLength         = fis.available();
        byte[] bytePvk          = new byte[fLength];
        fis.read(bytePvk,0,fLength);
        fis.close();
        ByteArrayInputStream bIn = new ByteArrayInputStream(bytePvk);
        DERInputStream dIn = new DERInputStream(bIn);
        ASN1Sequence      seq = (ASN1Sequence)dIn.readObject();
        if(seq.size()==9)
        {
            DERInteger n = (DERInteger)seq.getObjectAt(1);
            DERInteger e = (DERInteger)seq.getObjectAt(2);
            DERInteger d = (DERInteger)seq.getObjectAt(3);
            DERInteger p = (DERInteger)seq.getObjectAt(4);
            DERInteger q = (DERInteger)seq.getObjectAt(5);
            DERInteger dp = (DERInteger)seq.getObjectAt(6);
            DERInteger dq = (DERInteger)seq.getObjectAt(7);
            DERInteger qInv = (DERInteger)seq.getObjectAt(8);
            return new RSAPrivateKey(
                    n.getValue(),e.getValue(),d.getValue(),
                    p.getValue(),q.getValue(),dp.getValue(),
                    dq.getValue(),qInv.getValue());
        }
        return null;
    }
    /**
     * 以下是RSA算法的软件实现测试程序
     * @author 张荣华
     */
    public static void main(String[] args) {
        CRsa rsa= new CRsa();

        // 密钥生成测试
        // 密钥长度支持512 768 1024 2048 4096 再长也支持,但怕你的机器受不了
        System.out.println("=====================密钥生成测试======================");
        rsa.generateKeyPair(512);
        //rsa.savePukToFile("E:\\JavaProj\\temp\\puk.key");
        //rsa.savePvkToFile("E:\\JavaProj\\temp\\pvk.key");

        try {
            rsa.writePuk(rsa.getPublicKey(),"E:\\JavaProj\\temp\\puk.key");
            rsa.writePvk(rsa.getPrivateKey(),"E:\\JavaProj\\temp\\pvk.key");
//            rsa.readPuk("E:\\JavaProj\\temp\\puk.key");
//            rsa.readPvk("E:\\JavaProj\\temp\\pvk.key");
        }
        catch (IOException ex) {
        }
        System.out.println(rsa.getPublicKey().getModulus().toString(16));

        // 公钥加密私钥解密测试
        System.out.println("==================公钥加密私钥解密测试==================");
        String str="你好,张荣华!";
        byte[] indata=str.getBytes();
        int indatalen=indata.length;
        byte[] cipherData=null;
        byte[] plainData=null;
        try {
            cipherData=rsa.PublicKeyEncrypt(indata,indatalen);
        }
        catch (Exception ex) {
            //ex.printStackTrace();
        }
        try {
            plainData=rsa.PrivateKeyDecrypt(cipherData,cipherData.length);
        }
        catch (Exception ex) {
            //ex.printStackTrace();
        }
        System.out.println("解出的明文:\t"+new String(plainData));
        System.out.println("长度(字节)=\t"+plainData.length);
        // 数字签名及签名验证测试
        System.out.println("==================数字签名及签名验证测试==================");
        String strSign="这是一个签名测试!";
        byte[] signRes=null;
        try {
            // MD5WithRSA
            signRes=rsa.signData(5,strSign.getBytes());
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
        try {
            int success=rsa.verifySignData(signRes,strSign.getBytes());
            if(success==1)
                System.out.println("签名验证成功!");
            else
                System.out.println("签名验证失败!");
        }
        catch (Exception ex) {
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -