大文件加签处理

package com.bwf.util.crypt;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.bwf.log.LOG_TYPE;
import com.bwf.util.StringUtil;

/**
 * RSA大文件加密处理
 * 
 * @author BAOWEIFENG234
 * @version $Id: RSAUtils.java, v 0.1 2017-11-2 下午3:51:44 BAOWEIFENG234 Exp $
 */
public class RSAUtils {

    private static Logger      logger             = LoggerFactory.getLogger(LOG_TYPE.PAFF_SERVICE.val);

    /** 
     * 签名算法 
     */
    public static final String SIGN_ALGORITHMS    = "SHA1WithRSA";

    public static final String ENCRYPT_ALGORITHMS = "RSA";

    public static final String BYTE_ENCODE        = "UTF-8";

    /**
     * 测试用例
     * @param args
     */
    public static void main(String[] args) {
        //生成秘钥对
        //genKeyPair();
        String privateKeyStr = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMhsrk0lhECY/F46DnSdsKZxRtoW991Q2nfF0IPlyrYKvJMjaj592aRRW6p4Y7qlXecr8//yxGPd8c3v8CAPDZHLuG/yIQJMD9j8/XRUb483InwQc5OBj+GCGhW4gfObzuEjW6jVTyK1OkufxQw0AgGwWm4rt7S9KKlUDnzP+tQTAgMBAAECgYBNqBaNG7k3kk9Oby5ErwjQJNnwDLAzV22etM3LHVFC4bwZQsKavgaDLWbYEVeK7SIKPTSIelbv3wIe6hXfRhXaNC6ZqFjW9nCLUXrdFwuw40Rjxycsr42ZReb1RWbxkLe4WGms0rHwkJwLX35lS13evY5ee5VJdasrsswgS7TMkQJBAP2aHJ31HjLZ9Tmte/GQbx2jUaguhEFyB8XiL1z8THogf4uMubWqEQe35Tki5wVj+/jfRF65amac50YWcEtZupsCQQDKUdf7YOWBz6z1pcdFHPdR/aNKEOZAbR+OBcNAAehsQulemwgz5BDbCpyQQJGAFZkf2AipzRJtKZnE5l1vHUfpAkAGY4KDDDDFkS4XVOKBdGUINxwQg5N7XpcJiigtTIHUtcrgxhvLksw5CI3ywYlWXm1zmJRNWphum1dMMbaEf28vAkEAvaZ0mE5fNQzwa6BHqBCcAX6Jp28p9vCTqLTcLs7bCUi7q5QV31aFOl67Hjl4aqFUVVZT4J+8Cxn462qp4POIqQJAGonqu70ShsOOHbUGnNbqAuz1hYVH3A5cmfu8YIP0km6t9nauTmxJ7sou+WfPYg3bEznW4uzAibh0iwEHACwaow==";
        String publicKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIbK5NJYRAmPxeOg50nbCmcUbaFvfdUNp3xdCD5cq2CryTI2o+fdmkUVuqeGO6pV3nK/P/8sRj3fHN7/AgDw2Ry7hv8iECTA/Y/P10VG+PNyJ8EHOTgY/hghoVuIHzm87hI1uo1U8itTpLn8UMNAIBsFpuK7e0vSipVA58z/rUEwIDAQAB";

        //加签验签
        String fsign = signFile("D:/test/20160323FBSfbs21531416360.txt", privateKeyStr, BYTE_ENCODE);
        doCheckFile("D:/test/20160323FBSfbs21531416361.txt", fsign, publicKeyStr, BYTE_ENCODE);

        //加密解密
        encryptFileBig(privateKeyStr, "D:/test/2300.txt", "D:/test/aencrypt6360.encrypt");
        decryptFileBig(publicKeyStr, "D:/test/aencrypt6360.encrypt", "D:/test/aencrypt6360-1.txt");

        System.exit(0);
    }

    /** 
     * 随机生成密钥对 
     */
    public static void genKeyPair() {
        // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象  
        KeyPairGenerator keyPairGen = null;
        try {
            keyPairGen = KeyPairGenerator.getInstance(ENCRYPT_ALGORITHMS);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        keyPairGen.initialize(1024, new SecureRandom());
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        try {
            String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
            String privateKeyString = new String(Base64.encodeBase64(privateKey.getEncoded()));
            System.out.println("publicKeyString:" + publicKeyString);
            System.out.println("privateKeyString:" + privateKeyString);
            /*FileWriter pubfw = new FileWriter(filePath + "/publicKey.keystore");  
            FileWriter prifw = new FileWriter(filePath + "/privateKey.keystore");  
            BufferedWriter pubbw = new BufferedWriter(pubfw);  
            BufferedWriter pribw = new BufferedWriter(prifw);  
            pubbw.write(publicKeyString);  
            pribw.write(privateKeyString);  
            pubbw.flush();  
            pubbw.close();  
            pubfw.close();  
            pribw.flush();  
            pribw.close();  
            prifw.close(); */
        } catch (Exception e) {
            logger.error("genKeyPair-error{}", e);
        }
    }

    /**
     * RSA签名
     * 
     * @param filePath
     * @param privateKey
     * @param encode
     * @return
     */
    public static String signFile(String filePath, String privateKey, String encode) {
        FileInputStream fis = null;
        InputStreamReader isr = null;
        BufferedReader bfr = null;
        try {
            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
            KeyFactory keyf = KeyFactory.getInstance(ENCRYPT_ALGORITHMS);
            PrivateKey priKey = keyf.generatePrivate(priPKCS8);
            java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
            signature.initSign(priKey);
            fis = new FileInputStream(new File(filePath));
            isr = new InputStreamReader(fis, BYTE_ENCODE);
            bfr = new BufferedReader(isr);
            String lineTxt = "";
            while (StringUtil.isNotBlank(lineTxt = bfr.readLine())) {
                signature.update(lineTxt.getBytes(encode));
            }
            byte[] signed = signature.sign();
            String ret = new String(Base64.encodeBase64(signed));
            System.out.println("signed:" + ret);
            return ret;
        } catch (Exception e) {
            logger.error("signFile-error:{}" + e);
        } finally {
            if (bfr != null) {
                try {
                    bfr.close();
                } catch (IOException e) {
                }
            }
            if (isr != null) {
                try {
                    isr.close();
                } catch (IOException e) {
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                }
            }
        }
        return null;
    }

    /** 
     * RSA验签名检查 
     * @param content 待签名数据 
     * @param sign 签名值 
     * @param publicKey 分配给开发商公钥 
     * @param encode 字符集编码 
     * @return 布尔值 
     */
    public static boolean doCheckFile(String filePath, String sign, String publicKey, String encode) {
        FileInputStream fis = null;
        InputStreamReader isr = null;
        BufferedReader bfr = null;
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(ENCRYPT_ALGORITHMS);
            byte[] encodedKey = Base64.decodeBase64(publicKey);
            PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
            java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
            signature.initVerify(pubKey);
            fis = new FileInputStream(new File(filePath));
            isr = new InputStreamReader(fis, BYTE_ENCODE);
            bfr = new BufferedReader(isr);
            String lineTxt = "";
            while (StringUtil.isNotBlank(lineTxt = bfr.readLine())) {
                signature.update(lineTxt.getBytes(encode));
            }
            boolean bverify = signature.verify(Base64.decodeBase64(sign));
            return bverify;
        } catch (Exception e) {
            logger.error("doCheckFile-error:{}" + e);
        } finally {
            if (bfr != null) {
                try {
                    bfr.close();
                } catch (IOException e) {
                }
            }
            if (isr != null) {
                try {
                    isr.close();
                } catch (IOException e) {
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                }
            }
        }
        return false;
    }

    public static void encryptFileBig(String privateKeyStr, String srcFileName, String destFileName) {
        if (privateKeyStr == null) {
            new Exception("加密私钥为空, 请设置");
        }
        Cipher cipher = null;
        InputStream is = null;
        OutputStream out = null;
        CipherInputStream cis = null;
        try {
            // 使用默认RSA  
            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
                Base64.decodeBase64(privateKeyStr));
            KeyFactory keyf = KeyFactory.getInstance(ENCRYPT_ALGORITHMS);
            PrivateKey priKey = keyf.generatePrivate(priPKCS8);
            cipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
            cipher.init(Cipher.ENCRYPT_MODE, priKey);
            int blockSize = cipher.getBlockSize();
            is = new FileInputStream(srcFileName);
            File f = new File(srcFileName);
            int size = Integer.valueOf(String.valueOf(f.length()));
            byte[] encryptByte = new byte[size];
            is.read(encryptByte);
            out = new FileOutputStream(destFileName);
            int outputBlockSize = cipher.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) {
                    cipher.doFinal(encryptByte, i * blockSize, blockSize, cipherData,i * outputBlockSize);
                } else {
                    cipher.doFinal(encryptByte, i * blockSize, encryptByte.length - i * blockSize,cipherData, i * outputBlockSize);
                }
            }
            out.write(cipherData);
        } catch (Exception e) {
            logger.error("encryptFileBig-error:{}" + e);
        } finally {
            if (null != cis) {
                try {
                    cis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != out) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 文件解密
     * 
     * @param publicKeyStr
     * @param srcFileName
     * @param destFileName
     */
    public static void decryptFileBig(String publicKeyStr, String srcFileName, String destFileName) {
        Cipher cipher = null;
        InputStream is = null;
        OutputStream out = null;
        try {
            X509EncodedKeySpec encodedKey = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr));
            KeyFactory keyf = KeyFactory.getInstance(ENCRYPT_ALGORITHMS);
            PublicKey pubKey = keyf.generatePublic(encodedKey);
            cipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
            cipher.init(Cipher.DECRYPT_MODE, pubKey);
            File f = new File(srcFileName);
            is = new FileInputStream(f);
            out = new FileOutputStream(destFileName);
            int blockSize = cipher.getBlockSize();
            int size = Integer.valueOf(String.valueOf(f.length()));
            byte[] decryptByte = new byte[size];
            is.read(decryptByte);
            //分别对各块数据进行解密
            int j = 0;
            while ((decryptByte.length - j * blockSize) > 0) {
                out.write(cipher.doFinal(decryptByte, j * blockSize, blockSize));
                j++;
            }
        } catch (Exception e) {
            logger.error("decryptFileBig-error:{}" + e);
        } finally {
            if (null != out) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-ext-jdk16</artifactId>
<version>1.46</version>
</dependency>
<dependency>
     <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
  <version>1.8</version>
</dependency>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值