Java实现RSR对文件加密

来源:互联网 发布:Python私有成员 编辑:程序博客网 时间:2024/05/21 11:01

 说明bcprov-ext-jdk16-141.jar包在 http://www.bouncycastle.org/ 上下载

 

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package rsa;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Administrator
 */
public class GenKey {
    public static void main(String[] args){//创建密钥
        try {
            //创建密钥对生成器
            KeyPairGenerator KPG = KeyPairGenerator.getInstance("RSA");
            //初始化密钥生成器
            KPG.initialize(1024);
            //生成密钥对
            KeyPair KP=KPG.genKeyPair();
            //获取公钥和密钥
            PublicKey pbKey=KP.getPublic();
            PrivateKey prKey=KP.getPrivate();
            //保存公钥到文件
            FileOutputStream out=new FileOutputStream("RSAPublic.dat");
            ObjectOutputStream fileOut=new ObjectOutputStream(out);
            fileOut.writeObject(pbKey);
            //保存密钥到文件
            FileOutputStream outPrivate=new FileOutputStream("RSAPrivate.dat");
            ObjectOutputStream privateOut=new ObjectOutputStream(outPrivate);
            privateOut.writeObject(prKey);
        } catch (Exception ex) {
            Logger.getLogger(GenKey.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

}

 

 

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package rsatest;

import cipherinputstream.EncryptAndDecrypt;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.security.Key;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 *
 * @author Administrator
 */
public class RRSSA {

    public static void main(String[] args) {
        //要用作加密或解密的文件名
        String dataFileName = args[0];
        //是区分是加密还是解密,加密为encrypt,解密为decrypt
        String opMode = args[1];
        String keyFileName = null;
        //密钥存放的文件名
        if (opMode.equalsIgnoreCase("encrypt")) {
            keyFileName = "RSAPublic.dat";
        } else {
            keyFileName = "RSAPrivate.dat";
        }

        try {
            //生成密钥
            FileInputStream keyFIS = new FileInputStream(keyFileName);
            ObjectInputStream OIS = new ObjectInputStream(keyFIS);
            Key key = (Key) OIS.readObject();

            //创建并初始化密码器
            Cipher cp = Cipher.getInstance("RSA", new BouncyCastleProvider());//此处不能少
            //BouncyCastLeProvider类在bcprov-ext-jdk16-141.jar中
            if (opMode.equalsIgnoreCase("encrypt")) {

                cp.init(Cipher.ENCRYPT_MODE, key);
            } else if (opMode.equalsIgnoreCase("decrypt")) {
                cp.init(Cipher.DECRYPT_MODE, key);
            } else {
                return;
            }

            FileInputStream dataFIS = new FileInputStream(dataFileName);
            //取得要加密的数据
            int size = dataFIS.available();
            byte[] encryptByte = new byte[size];
            dataFIS.read(encryptByte);


            //如果是加密操作
            if (opMode.equalsIgnoreCase("encrypt")) {
                //建立文件输出流
                FileOutputStream FOS = new FileOutputStream("mi.txt");
                //RSA算法必须采用分块加密
                //取得RSA加密的块的大小
                int blockSize = cp.getBlockSize();
                //根据给定的输入长度 inputLen(以字节为单位),返回保存下一个 update 或 doFinal 操作结果所需的输出缓冲区长度(以字节为单位)。
                int outputBlockSize = cp.getOutputSize(encryptByte.length);

                //确定要加密的次数(加密块的个数)
                int leavedSize = encryptByte.length % blockSize;
                int blocksNum = leavedSize == 0 ? encryptByte.length / blockSize
                        : encryptByte.length / blockSize + 1;
   
                byte[] cipherData = new byte[blocksNum * outputBlockSize];


                //对每块数据分别加密
                for (int i = 0; i < blocksNum; i++) {

                    if ((encryptByte.length - i * blockSize) > blockSize) {
                        cp.doFinal(encryptByte, i * blockSize, blockSize, cipherData, i * outputBlockSize);
                    } else {
                        cp.doFinal(encryptByte, i * blockSize, encryptByte.length - i * blockSize, cipherData, i * outputBlockSize);
                    }

                                    }

               FOS.write(cipherData);

                FOS.close();

            } else {//如果是解密操作

                FileOutputStream FOS = new FileOutputStream("jiemi.txt");
                int blockSize = cp.getBlockSize();
                int j = 0;

                //分别对各块数据进行解密
                while ((encryptByte.length - j * blockSize) > 0) {
                    FOS.write(cp.doFinal(encryptByte, j * blockSize, blockSize));
                    j++;
                }

                FOS.close();

            }
        } catch (Exception ex) {
            Logger.getLogger(EncryptAndDecrypt.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}