PGP加密文件和解密文件

来源:互联网 发布:java多线程上传文件 编辑:程序博客网 时间:2024/05/17 07:06

首先,需要jar包如下:
cryptix-jce-api.jar
cryptix-jce-provider.jar
cryptix-message-api.jar
cryptix-openpgp-provider.jar
cryptix-pki-api.jar

然后需要写两个class,一个是PGP加密解密功能的类,一个是给其他类使用的工具类。
使用的时候调用工具类PGPEncryptDecrypt就好了。

工具类PGPEncryptDecrypt :

import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.text.SimpleDateFormat;import java.util.Date;import cryptix.pki.KeyBundle;public class PGPEncryptDecrypt {    //解密文件路径    private static String decryptFilePath = "";    //解密后新生成的文件    private static String decrypt_New = "";    //解密后生成的新文件    private static File decryptFile_New = null;    //须解密文件    private static File decryptFile = null;    //须解密文件名    private static String decryptFileName = "";    //须加密文件    private static File encryptFile = null;    //加密后生成的新文件    private static File encryptFile_New = null;    //公钥证书    private static File pubKey = null;    // 私钥证书    private static File prikey = null;    // 证书密码    private static String password = "";    //原始文件路径    private  static String plaintextPath = "";    //原始文件文件名    private static String plaintextFileName = "";    //加密文件路径    private static String encryptFilePath = "";    //加密后新生成的文件    private static String encrypt_newFileName = "";    //证书文件路径    private static String certFilePath = "";    //公钥名    private static String publicKeyFileName = "";    //私钥名    private static String privateKeyFileName = "";    //将日期以 yyyyMMdd 的格式输出    private static final SimpleDateFormat compactDateFormatter = new SimpleDateFormat("yyyyMMdd");    private static String formatCompactDate(Date date) {        if(date==null){            return "";        }        return compactDateFormatter.format(date);    }    ///////////////////////////////////////////加密用////////////////////////////////////////////////    //签名并加密文件,并且将签名加密后的文件内容写入到新的文件中    public static void signEncrypt(String pswd,String orifilepath,String orifilename,String encryfilepath,String encryptnewFileName,String certpath,String pubkeyname,String prikeyname){        password = pswd;        plaintextPath = orifilepath;        plaintextFileName = orifilename;        encryptFilePath = encryfilepath;        encrypt_newFileName = encryptnewFileName;        certFilePath = certpath;        publicKeyFileName = pubkeyname;        privateKeyFileName = prikeyname;        encryptFile = new File(plaintextPath,plaintextFileName);        pubKey = new File(certFilePath,publicKeyFileName);        prikey = new File(certFilePath,privateKeyFileName);        encryptFile_New = new File(encryptFilePath,encrypt_newFileName);        System.out.println("password=>"+password);        System.out.println("plaintextPath=>"+plaintextPath);        System.out.println("plaintextFileName=>"+plaintextFileName);        System.out.println("encryptFilePath=>"+encryptFilePath);        System.out.println("encrypt_newFileName=>"+encrypt_newFileName);        System.out.println("certFilePath=>"+certFilePath);        System.out.println("publicKeyFileName=>"+publicKeyFileName);        System.out.println("privateKeyFileName=>"+privateKeyFileName);        System.out.println("encryptFile.getName()=>"+encryptFile.getName());        if(!encryptFile.exists()){            System.out.println("Encrypt file is not exists!");            throw new RuntimeException("Encrypt file is not exists!");        }        byte [] encrypts = pgpEncryptAndSign(IOUtil.read(encryptFile), pubKey, prikey, password);        IOUtil.writeAsText(encryptFile_New, new String(encrypts));    }    /** 使用PGP证书签名和加密原始文件     *      * @param plain     *            原始文件     * @param publicFile     *            公钥     * @param privateFile     *            私钥     * @param password     *            私钥密码     * @return 返回签名加密后的密文     */    private static byte[] pgpEncryptAndSign(byte[] plain, File publicKeyFile,File privateKeyFile, String password) {        try {            InputStream pubInputStream = new FileInputStream(publicKeyFile);            InputStream priInputStream = new FileInputStream(privateKeyFile);            // 将公钥文件转换为PGP的KeyBundle(加密需要使用KeyBundle)            KeyBundle publicKey = PGPUtil.streamToKeyBundle(pubInputStream);            // 将私钥文件转换为PGP的KeyBundle(签名需要使用KeyBundle)            KeyBundle privateKey = PGPUtil.streamToKeyBundle(priInputStream);            // 返回加密后的密文            return PGPUtil.signAndEncrypt(plain, privateKey, password,                    publicKey);        } catch (Exception e) {            System.out.println("Use PGP Sign And Encrypt Fail!  excepted:"+ e);            throw new RuntimeException();        }    }    ///////////////////////////////////////////加密用////////////////////////////////////////////////    ///////////////////////////////////////////解密用////////////////////////////////////////////////    /**     * 解密并验签文件     * 并且将解密的内容写入到指定的文件中     */    public static void decryptVerify(String decrypt_pswd,String decrypt_filepath , String decrypt_filename , String decryptnewfilename,String decrypt_certpath,String decrypt_pubkeyname,String decrypt_prikeyname){        password = decrypt_pswd;        certFilePath = decrypt_certpath;        publicKeyFileName = decrypt_pubkeyname;        privateKeyFileName = decrypt_prikeyname;        decryptFilePath = decrypt_filepath;        decryptFileName = decrypt_filename;        decrypt_New = decryptnewfilename;        decryptFile = new File(decryptFilePath,decryptFileName);        decryptFile_New = new File(decryptFilePath,decrypt_New);        pubKey = new File(certFilePath,publicKeyFileName);        prikey = new File(certFilePath,privateKeyFileName);        System.out.println("password=>"+password);        System.out.println("plaintextPath=>"+plaintextPath);        System.out.println("plaintextFileName=>"+plaintextFileName);        System.out.println("decryptFilePath=>"+decryptFilePath);        System.out.println("decrypt_newFileName=>"+decryptFileName);        System.out.println("certFilePath=>"+certFilePath);        System.out.println("publicKeyFileName=>"+publicKeyFileName);        System.out.println("privateKeyFileName=>"+privateKeyFileName);        System.out.println("decryptFile.getName()=>"+decryptFile.getName());        if(!decryptFile.exists()){            System.out.println("Decrypt file is not exists!");            throw new RuntimeException("Decrypt file is not exists!");        }        byte [] decrypts = pgpDecryptCryptograph(IOUtil.read(decryptFile), pubKey, prikey, password);        IOUtil.writeAsText(decryptFile_New, new String(decrypts));    }    /**     * 使用PGP私钥对密文解密     *      * @param cryptograph     *            密文内容     * @param publicFile     *            公钥文件     * @param privateFile     *            私钥文件     * @param password     *            私钥密码     * @return 返回解密验签后明文     */    private static byte[] pgpDecryptCryptograph(byte [] cryptograph,File publicKeyFile,File privateKeyFile,String password){        try {            InputStream pubInputStream  = new FileInputStream(publicKeyFile);            InputStream priInputStream = new FileInputStream(privateKeyFile);            //将私钥文件转换为PGP的KeyBundle(签名需要使用KeyBundle)            KeyBundle privateKey = PGPUtil.streamToKeyBundle(priInputStream);            //将公钥文件转换为PGP的KeyBundle(加密需要使用KeyBundle)            KeyBundle publicKey = PGPUtil.streamToKeyBundle(pubInputStream);            return PGPUtil.decryptVerify(cryptograph, privateKey, password, publicKey);        } catch (Exception e) {            System.out.println("Use PGP Decrypt Verify Fail!  exception:"+e);            e.printStackTrace();            throw new RuntimeException();        }    }    ///////////////////////////////////////////解密用////////////////////////////////////////////////}

功能类PGPUtil:

import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStream;import java.security.NoSuchAlgorithmException;import java.security.Security;import java.security.UnrecoverableKeyException;import java.util.ArrayList;import java.util.Collection;import java.util.List;import cryptix.message.EncryptedMessage;import cryptix.message.EncryptedMessageBuilder;import cryptix.message.KeyBundleMessage;import cryptix.message.LiteralMessage;import cryptix.message.LiteralMessageBuilder;import cryptix.message.Message;import cryptix.message.MessageException;import cryptix.message.MessageFactory;import cryptix.message.NotEncryptedToParameterException;import cryptix.message.SignedMessage;import cryptix.message.SignedMessageBuilder;import cryptix.openpgp.PGPArmouredMessage;import cryptix.pki.KeyBundle;public class PGPUtil {    //这个一定要有 不然会报这个错java.security.NoSuchAlgorithmException: Algorithm not found.    static{        Security.addProvider(new cryptix.jce.provider.CryptixCrypto());        Security.addProvider(new cryptix.openpgp.provider.CryptixOpenPGP() );    }    ///////////////////////////////////////////加密用////////////////////////////////////////////////    /**     * 流转换为PGP KeuBundle 对象     * @param inputStream   Key     * @return  转换后的 KeuBundle     * @throws MessageException     * @throws IOException     */    public static KeyBundle streamToKeyBundle(InputStream inputStream) throws MessageException, IOException {        MessageFactory messageFactory = null;        try {            messageFactory = MessageFactory.getInstance("OpenPGP");        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        }        Collection msgs = messageFactory.generateMessages(inputStream);        KeyBundleMessage keybm = (KeyBundleMessage)msgs.iterator().next();        return keybm.getKeyBundle();    }    /**     * 签名加密     * @param plain         明文       * @param privateKey    私钥       * @param keypass       私钥密码     * @param recipientKeys 公钥     * @return              返回签名加密后的数据     * @throws UnrecoverableKeyException     * @throws MessageException     */    public static byte [] signAndEncrypt(byte[] plain,KeyBundle privateKey,String keypass,List<KeyBundle> recipientKeys) throws UnrecoverableKeyException, MessageException{        return PGPUtil.encrypt(PGPUtil.sign(plain, privateKey, keypass),recipientKeys);    }    /**     * 签名加密     * @param plain         明文       * @param privateKey    私钥       * @param keypass       私钥密码     * @param recipientKeys 公钥     * @return              返回签名加密后的数据     * @throws UnrecoverableKeyException     * @throws MessageException     */    public static byte [] signAndEncrypt(byte[] plain,KeyBundle privateKey,String keypass,KeyBundle publicKey) throws UnrecoverableKeyException, MessageException{        return PGPUtil.encrypt(PGPUtil.sign(plain, privateKey, keypass),publicKey);    }    /**     * 使用多个公钥对明文加密     * @param plain         明文     * @param recipientKeys 公钥集合     * @return              加密后的明文     * @throws MessageException     */    public static byte[] encrypt(byte[] plain,List<KeyBundle> recipientKeys) throws MessageException{        LiteralMessage literal = buildLiteralMessage(plain);        EncryptedMessageBuilder emb = null;        try {            emb = EncryptedMessageBuilder.getInstance("OpenPGP");        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        }        emb.init(literal);        //添加接受者        for(KeyBundle key : recipientKeys){            emb.addRecipient(key);        }        //压缩        emb.setAttribute("compressed", "true");        //得到加密信息        Message msg = emb.build();        PGPArmouredMessage pgpMsg = new PGPArmouredMessage(msg);        return pgpMsg.getEncoded();    }    /**     * 使用单张公钥加密     * @param plain     明文       * @param publicKey 公钥     * @return  返回加密后的密文     * @throws MessageException     */    public static byte[] encrypt(byte[] plain,KeyBundle publicKey) throws MessageException{        List<KeyBundle> list = new ArrayList<KeyBundle>();        list.add(publicKey);        return encrypt(plain,list);    }    /**     * 使用私钥和密码对明文签名     * @param plain         明文     * @param privateKey    私钥     * @param keypass       私钥密码     * @return              签名后的明文     * @throws MessageException     * @throws UnrecoverableKeyException     */    public static byte[] sign(byte[] plain,KeyBundle privateKey,String keypass)throws MessageException,UnrecoverableKeyException{        SignedMessageBuilder smb = null;        try {            smb = SignedMessageBuilder.getInstance("OpenPGP");        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        }        // SignedMessageBuilder smb = SignedMessageBuilder.getInstance("OpenPGP/V3");        LiteralMessage literal = buildLiteralMessage(plain);        smb.init(literal);        smb.addSigner(privateKey, keypass.toCharArray());        Message msg = smb.build();        PGPArmouredMessage armoured = new PGPArmouredMessage(msg);        return armoured.getEncoded();    }    private static LiteralMessage buildLiteralMessage(byte[] message) throws MessageException{        LiteralMessageBuilder lmb = null;        try {            lmb = LiteralMessageBuilder.getInstance("OpenPGP");        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        }        lmb.init(message);        LiteralMessage literal = (LiteralMessage)lmb.build();        return literal;    }    ///////////////////////////////////////////加密用////////////////////////////////////////////////    ///////////////////////////////////////////解密用////////////////////////////////////////////////    /**     * 解密验签     * @param encrypted     密文       * @param privateKey    私钥     * @param keypass       私钥密码     * @param publicKey     公钥     * @return              返回明文     * @throws UnrecoverableKeyException     * @throws MessageException     * @throws IOException     * @throws NotEncryptedToParameterException     */    public static byte[] decryptVerify(byte[] encrypted,KeyBundle privateKey,String keypass,KeyBundle publicKey) throws UnrecoverableKeyException, MessageException, IOException, NotEncryptedToParameterException{        return PGPUtil.verify(PGPUtil.decrypt(encrypted, privateKey, keypass), publicKey);    }    /**     * 使用私钥和密码解密加密后的数据     * @param encrypted     PGP加密过的数据     * @param privateKey    私钥     * @param keypass       私钥密码     * @return              解密后的明文     * @throws MessageException     * @throws IOException     * @throws UnrecoverableKeyException     * @throws NotEncryptedToParameterException     */    public static byte[] decrypt(byte[] encrypted,KeyBundle privateKey,String keypass) throws MessageException, IOException, UnrecoverableKeyException, NotEncryptedToParameterException{        MessageFactory mf = null;        try {            mf = MessageFactory.getInstance("OpenPGP");        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        }        Collection msgs = mf.generateMessages(new ByteArrayInputStream(encrypted));        //得到集合中的EncryptedMessage对象        Message message = (Message)msgs.iterator().next();        if (!(message instanceof EncryptedMessage)) {            throw new MessageException("Not a encrypted message.");        }        EncryptedMessage em = (EncryptedMessage)message;        Message msg = em.decrypt(privateKey,keypass.toCharArray());        return ((LiteralMessage)msg).getBinaryData();    }    /**     * 验证Message     * @param signed    验证的内容     * @param publickey 公钥     * @return          返回验证后的内容     * @throws MessageException     * @throws IOException     */    public static byte[] verify(byte[] signed,KeyBundle publickey) throws MessageException, IOException{        MessageFactory mf = null;        try {            mf = MessageFactory.getInstance("OpenPGP");        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        }        Message msg = (Message)mf.generateMessages(new ByteArrayInputStream(signed)).iterator().next();        if (!(msg instanceof SignedMessage)) {            throw new MessageException(" Not a signed message.");        }        SignedMessage sm = (SignedMessage)msg;        if (sm.verify(publickey)) {        } else {            throw new MessageException(" Signature verify fail. ");        }        if (!(sm.getContents() instanceof LiteralMessage)){            throw new MessageException(" Not a signed message.");        }        LiteralMessage lm = (LiteralMessage)sm.getContents();        return lm.getBinaryData();    }    ///////////////////////////////////////////解密用////////////////////////////////////////////////}

最后是调用:

//------------------------PGP encrypt decrypt------------------------String PGPpassword = "PGP私钥密码";String filepath = "存放文件的路径";String oripath = "存放源文件的文件夹";String encryptpath = "存放加密后文件的文件夹";String decryptpath = "存放解密后文件的文件夹";String orifilename = "源文件文件名";String encryptfilename = "加密文件文件名";String decryptfilename = "解密文件文件名";String keypath = "PGP私钥存放路径";String publicPGPkey = "公钥文件名";String privatePGPkey = "私钥文件名";//------------------------PGP encrypt decrypt------------------------/*执行加密*/        PGPEncryptDecrypt.signEncrypt(PGPpassword, filepath+oripath, orifilename, filepath+encryptpath, encryptfilename, keypath, publicPGPkey, privatePGPkey);/*执行解密操作*/          PGPEncryptDecrypt.decryptVerify(PGPpassword,filepath,encryptpath+encryptfilename,decryptpath+decryptfilename, keypath, publicPGPkey, privatePGPkey);