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

📄 crsa.java

📁 说明: 1、里面有什么: 1.1、org.bouncycastle.*下的所有软件是bouncycastle组织开发的软件包 1.2、org.infosecurity.*下的软件包括
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package org.infosecurity.cryptography;

/**
 * <p>Title: RSA算法的软件实现 </p>
 * <p>Description: RSA算法的软件实现,功能包括:公钥加密私钥解密</p>
 * <p>数字签名和签名验证,密钥对(公私钥)的生成,遵循PKCS标准</p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: 中信信息安全组织(CISO)</p>
 * @author 张荣华
 * @version 1.0.2003.0704
 */

import java.io.*;
import java.math.*;
import java.util.*;
import java.security.SecureRandom;
import org.bouncycastle.asn1.*;
import org.bouncycastle.asn1.x509.*;
import org.bouncycastle.util.encoders.*;

public class CRsa extends Object implements Serializable {
    // HASH算法的缺省摘要的信息
    private final static byte[] SHA1_DIGEST_INFO = {
        (byte)0x30, (byte)0x21, (byte)0x30, (byte)0x09, (byte)0x06,
        (byte)0x05, (byte)0x2b, (byte)0x0e, (byte)0x03, (byte)0x02,
        (byte)0x1a, (byte)0x05, (byte)0x00, (byte)0x04, (byte)0x14,
        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
    };

    private final static byte[] MD5_DIGEST_INFO = {
        (byte)0x30, (byte)0x20, (byte)0x30, (byte)0x0c, (byte)0x06,
        (byte)0x08, (byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86,
        (byte)0xf7, (byte)0x0d, (byte)0x02, (byte)0x05, (byte)0x05,
        (byte)0x00, (byte)0x04, (byte)0x10, (byte)0x00, (byte)0x00,
        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
	};
    private byte[] mTDefault=null;
    private int    mLen=0;
    //
    private SecureRandom secureRd=new SecureRandom();
    private static BigInteger ONE = BigInteger.valueOf(1);
    private static BigInteger TWO = BigInteger.valueOf(2);
    // ebase为17
    private static BigInteger eBase = BigInteger.valueOf(0x11);
    RSAPublicKey pukParam=null;
    RSAPrivateKey pvkParam=null;

    public CRsa() {

    }
    /**
     *   设置公钥
     */
    public void setPublicKey(RSAPublicKey puk)
    {
        this.pukParam = puk;
    }
    /**
     *   设置私钥
     */
    public void setPrivateKey(RSAPrivateKey pvk)
    {
        this.pvkParam = pvk;
        this.pukParam = new RSAPublicKey(pvk.getModulus(),pvk.getExponent());
    }
    /**
     *   公钥加密
     */
    public byte[] PublicKeyEncrypt(byte[] indata,int indatalen)
            throws DataLengthException
    {
        int k=getInputBlockSize(true);
        byte EncryptBlock[]=null;
        // PS依据输入数据的长度>8
        if (indatalen > getInputBlockSize(true)-10)
        {
            throw new DataLengthException("输入RSA加密的数据太长.\n");
        }
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        byte[] PS=new byte[(getOutputBlockSize(true)-indatalen-2)];
        for(int i=0;i<PS.length;i++)
        {
            PS[i]=(byte)(secureRd.nextInt(255)+1);
        }
        try
        {
            baos.write((byte)0x02);
            baos.write(PS);
            baos.write((byte)0x00);
            baos.write(indata);
        }catch(IOException ioe){
            ioe.printStackTrace();
        }
        EncryptBlock=baos.toByteArray();
        BigInteger  input = new BigInteger(1, EncryptBlock);
        byte[]      output=null;
        output = input.modPow(pukParam.getExponent(), pukParam.getModulus()).toByteArray();
        if (output[0] == 0 && output.length > getOutputBlockSize(true))//比输出长度长,截断
        {
            byte[]  tmp = new byte[output.length - 1];
            System.arraycopy(output, 1, tmp, 0, tmp.length);
            return tmp;
        }
        if (output.length < getOutputBlockSize(true))                 // 比输出长度短,增长
        {
            byte[]  tmp = new byte[getOutputBlockSize(true)];
            System.arraycopy(output, 0, tmp, tmp.length - output.length, output.length);
            return tmp;
        }
        return output;
    }
    /**
     *   私钥解密
     */
    public byte[] PrivateKeyDecrypt(byte[] indata,int indatalen)
            throws DataLengthException
    {
        int padLength=0;
        if (indatalen > getInputBlockSize(false))
        {
            throw new DataLengthException("输入RSA解密的数据太长.");
        }
        byte[]      output=null;
        BigInteger input=new BigInteger(1,indata);
        output = input.modPow(pvkParam.getPrivateExponent(), pukParam.getModulus()).toByteArray();
        if(output.length<10)
            throw new DataLengthException("消息格式不对.");
        if(output[0]!=(byte)0x02)
        {
            throw new DataLengthException("不是公钥操作的结果");
        }
        int start=0;
        int outLen=output.length;
        while(output[start]!=(byte)0x00)
        {
            start++;
            if(start>=outLen)
                throw new DataLengthException("无效的填充数据!");
        }
        start++;          // 跳过0
        byte tm[]=new byte[outLen-start];
        try {
            System.arraycopy(output,start,tm,0,tm.length);
        }
        catch (Exception ex) {
            return null;
        }
        return tm;
    }
    /**
     * 数字签名
     * @param HashAlgorith 散列算法(5--md5 3--sha1)
     * @param indata       输入数据
     */
    public byte[] signData(int HashAlgorithm,byte[] indata)
            throws Exception
    {
        int indatalen=indata.length;
        byte[] hashRes=null;
        int blockLen=getInputBlockSize(true);
        if(HashAlgorithm==5)
            hashRes=new byte[16];
        else if(HashAlgorithm==3)
            hashRes=new byte[20];
        else
            throw new Exception("不支持的散列算法!");
        if(indata==null||indata.length==0)
            throw new Exception("输入数据为空");
        if(HashAlgorithm==5)
        {
            // 生成摘要
            mTDefault=new byte[MD5_DIGEST_INFO.length];
            mLen=16;
            System.arraycopy(MD5_DIGEST_INFO,0,mTDefault,0,mTDefault.length);
            CMd5 md5=new CMd5();
            for(int i=0;i<indatalen;i++)
                md5.update(indata[i]);
            md5.doFinal(hashRes,0);
            // 摘要编码
            // 待编码的长度要比密钥的长度小1
            byte inbyte[]=encode(hashRes,getOutputBlockSize(true)-1,16);
            // 签名
            byte[]      signData=null;
            BigInteger input=new BigInteger(1,inbyte);
            signData = input.modPow(pvkParam.getPrivateExponent(), pukParam.getModulus()).toByteArray();
            // 如果是正数转成一个字节数组,我们将得到一个以0开头的结果
            if (signData[0] == 0 && signData.length > getOutputBlockSize(true))//比输出长度长,截断
            {
                byte[]  tmp = new byte[signData.length - 1];
                System.arraycopy(signData, 1, tmp, 0, tmp.length);
                return tmp;
            }
            if (signData.length < getOutputBlockSize(true))                 // 比输出长度短,增长
            {
                byte[]  tmp = new byte[getOutputBlockSize(true)];
                System.arraycopy(signData, 0, tmp, tmp.length - signData.length, signData.length);
                return tmp;
            }
            return signData;
        }
        if(HashAlgorithm==3)
        {
            mTDefault=new byte[SHA1_DIGEST_INFO.length];
            mLen=20;
            System.arraycopy(SHA1_DIGEST_INFO,0,mTDefault,0,mTDefault.length);
            CSha1 sha1=new CSha1();
            for(int i=0;i<indatalen;i++)
                sha1.update(indata[i]);
            sha1.doFinal(hashRes,0);
            // 摘要编码
             byte inbyte[]=encode(hashRes,getOutputBlockSize(true)-1,20);
             // 签名
             byte[]      signData=null;
             BigInteger input=new BigInteger(1,inbyte);
             signData = input.modPow(pvkParam.getPrivateExponent(), pukParam.getModulus()).toByteArray();
             if (signData[0] == 0 && signData.length > getOutputBlockSize(true))//比输出长度长,截断
             {
                 byte[]  tmp = new byte[signData.length - 1];
                 System.arraycopy(signData, 1, tmp, 0, tmp.length);
                 return tmp;
             }
             if (signData.length < getOutputBlockSize(true))                 // 比输出长度短,增长
             {
                 byte[]  tmp = new byte[getOutputBlockSize(true)];
                 System.arraycopy(signData, 0, tmp, tmp.length - signData.length, signData.length);
                 return tmp;
             }
             return signData;
        }
        return null;
    }
    /**
     *   验证数字签名
     */
    public int verifySignData(byte[] indata,byte[] plainData)throws Exception
    {
        try {
            if(indata.length>getInputBlockSize(false))
                throw new Exception("签名的输入长度过长!");
            BigInteger input=new BigInteger(1,indata);
            byte[] out = input.modPow(pukParam.getExponent(), pukParam.getModulus()).toByteArray();
            byte[] bEncodedHash=decode(out);
            ByteArrayInputStream bIn=null;
            bIn = new ByteArrayInputStream(bEncodedHash);
            DERInputStream dIn = new DERInputStream(bIn);
            ASN1Sequence   seq = (ASN1Sequence)dIn.readObject();
            if(seq.size()==2)
            {
                DigestInfo digestInf=DigestInfo.getInstance(seq);
                AlgorithmIdentifier aID=digestInf.getAlgorithmId();
                if(aID.getObjectId().getId().equals("1.2.840.113549.2.5"))//MD5
                {
                    // 生成摘要
                    int plainDataLength=0;
                    plainDataLength=plainData.length;
                    byte[] plainHash=new byte[16];
                    CMd5 md5=new CMd5();
                    for(int i=0;i<plainDataLength;i++)
                        md5.update(plainData[i]);
                    md5.doFinal(plainHash,0);
                    byte[] digest=digestInf.getDigest();
                   for(int i=0;i<md5.getDigestSize();i++)
                   {
                       //System.out.println("result="+digest[i]+"plain="+plainHash[i]);
                       if(digest[i]==plainHash[i])
                       {
                           //调试输出语句
                           continue;
                       }
                       else
                           return 0;
                   }
                   return 1;
                }
                else if(aID.getObjectId().getId().equals("1.3.14.3.2.26"))
                {
                    // 生成摘要
                    int plainDataLength=0;
                    plainDataLength=plainData.length;
                    byte[] plainHash=new byte[20];
                    CSha1 sha1=new CSha1();
                    for(int i=0;i<plainDataLength;i++)
                        sha1.update(plainData[i]);
                    sha1.doFinal(plainHash,0);
                    byte[] digest=digestInf.getDigest();
                   for(int i=0;i<sha1.getDigestSize();i++)
                   {
                       if(digest[i]==plainHash[i])
                           continue;
                       else
                           return 0;
                   }
                   return 1;
                }
                else
                {
                   // 目前不支持该算法
                    return 0;
                }
            }
            else
                return 0;
        }
        catch (Exception e) {

⌨️ 快捷键说明

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