非对称加密RSA加密文件

Posted jinxinblogs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了非对称加密RSA加密文件相关的知识,希望对你有一定的参考价值。

RSA加密文件

   关于RSA非对称加密很多地方都有讲解。

  下面是AES

   AES 类

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * <p>
 * AES加密解密工具包
 * </p>
 *
 * @author IceWee
 * @date 2012-5-18
 * @version 1.0
 */
public class AESUtils 

    private static final String ALGORITHM = "AES";
    private static final int KEY_SIZE = 256;
    private static final int CACHE_SIZE = 1024;

    /**
     * <p>
     * 生成随机密钥
     * </p>
     *
     * @return
     * @throws Exception
     */
    public static String getSecretKey() throws Exception 
        return getSecretKey(null);
        //return "X9qY3q630+wI/kLuKo1cBA==";
    

    /**
     * <p>
     * 生成密钥
     * </p>
     *
     * @param seed 密钥种子
     * @return
     * @throws Exception
     */
    public static String getSecretKey(String seed) throws Exception 
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
        SecureRandom secureRandom;
        if (seed != null && !"".equals(seed)) 
            secureRandom = new SecureRandom(seed.getBytes());
         else 
            secureRandom = new SecureRandom();
        
        keyGenerator.init(KEY_SIZE, secureRandom);
        SecretKey secretKey = keyGenerator.generateKey();
        System.out.println("密钥种子:"+Base64Utils.encode(secretKey.getEncoded()));
        return Base64Utils.encode(secretKey.getEncoded());
    

    /**
     * <p>
     * 加密
     * </p>
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, String key) throws Exception 
        Key k = toKey(Base64Utils.decode(key));
        byte[] raw = k.getEncoded();
        SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        return cipher.doFinal(data);
    

    /**
     * <p>
     * 文件加密
     * </p>
     *
     * @param key
     * @param sourceFilePath
     * @param destFilePath
     * @throws Exception
     */
    public static void encryptFile(String key, String sourceFilePath, String destFilePath) throws Exception 
        File sourceFile = new File(sourceFilePath);
        File destFile = new File(destFilePath);
        if (sourceFile.exists() && sourceFile.isFile()) 
            if (!destFile.getParentFile().exists()) 
                destFile.getParentFile().mkdirs();
            
            destFile.createNewFile();
            InputStream in = new FileInputStream(sourceFile);
            OutputStream out = new FileOutputStream(destFile);
            Key k = toKey(Base64Utils.decode(key));
            byte[] raw = k.getEncoded();
            SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            CipherInputStream cin = new CipherInputStream(in, cipher);
            byte[] cache = new byte[CACHE_SIZE];
            int nRead = 0;
            while ((nRead = cin.read(cache)) != -1) 
                out.write(cache, 0, nRead);
                out.flush();
            
            out.close();
            cin.close();
            in.close();
        
    

    /**
     * <p>
     * 解密
     * </p>
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, String key) throws Exception 
        Key k = toKey(Base64Utils.decode(key));
        byte[] raw = k.getEncoded();
        SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        return cipher.doFinal(data);
    

    /**
     * <p>
     * 文件解密
     * </p>
     *
     * @param key
     * @param sourceFilePath
     * @param destFilePath
     * @throws Exception
     */
    public static void decryptFile(String key, String sourceFilePath, String destFilePath) throws Exception 
        File sourceFile = new File(sourceFilePath);
        File destFile = new File(destFilePath);
        if (sourceFile.exists() && sourceFile.isFile()) 
            if (!destFile.getParentFile().exists()) 
                destFile.getParentFile().mkdirs();
            
            destFile.createNewFile();
            FileInputStream in = new FileInputStream(sourceFile);
            FileOutputStream out = new FileOutputStream(destFile);
            Key k = toKey(Base64Utils.decode(key));
            byte[] raw = k.getEncoded();
            SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            CipherOutputStream cout = new CipherOutputStream(out, cipher);
            byte[] cache = new byte[CACHE_SIZE];
            int nRead = 0;
            while ((nRead = in.read(cache)) != -1) 
                cout.write(cache, 0, nRead);
                cout.flush();
            
            cout.close();
            out.close();
            in.close();
        
    

    /**
     * <p>
     * 转换密钥
     * </p>
     *
     * @param key
     * @return
     * @throws Exception
     */
    private static Key toKey(byte[] key) throws Exception 
        SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);
        return secretKey;
    

 

Base64Utils.java

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;



/**
 * <p>
 * BASE64编码解码工具包
 * </p>
 * <p>
 * 依赖javabase64-1.3.1.jar
 * </p>
 *
 * @author IceWee
 * @date 2012-5-19
 * @version 1.0
 */
public class Base64Utils 

    /**
     * 文件读取缓冲区大小
     */
    private static final int CACHE_SIZE = 1024;

    /**
     * <p>
     * BASE64字符串解码为二进制数据
     * </p>
     *
     * @param base64
     * @return
     * @throws Exception
     */
    public static byte[] decode(String base64) throws Exception 
        return Base64.decode(base64);
    

    /**
     * <p>
     * 二进制数据编码为BASE64字符串
     * </p>
     *
     * @param bytes
     * @return
     * @throws Exception
     */
    public static String encode(byte[] bytes) throws Exception 
        return new String(Base64.encode(bytes));
    

    /**
     * <p>
     * 将文件编码为BASE64字符串
     * </p>
     * <p>
     * 大文件慎用,可能会导致内存溢出
     * </p>
     *
     * @param filePath 文件绝对路径
     * @return
     * @throws Exception
     */
    public static String encodeFile(String filePath) throws Exception 
        byte[] bytes = fileToByte(filePath);
        return encode(bytes);
    

    /**
     * <p>
     * BASE64字符串转回文件
     * </p>
     *
     * @param filePath 文件绝对路径
     * @param base64 编码字符串
     * @throws Exception
     */
    public static void decodeToFile(String filePath, String base64) throws Exception 
        byte[] bytes = decode(base64);
        byteArrayToFile(bytes, filePath);
    

    /**
     * <p>
     * 文件转换为二进制数组
     * </p>
     *
     * @param filePath 文件路径
     * @return
     * @throws Exception
     */
    public static byte[] fileToByte(String filePath) throws Exception 
        byte[] data = new byte[0];
        File file = new File(filePath);
        if (file.exists()) 
            FileInputStream in = new FileInputStream(file);
            ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
            byte[] cache = new byte[CACHE_SIZE];
            int nRead = 0;
            while ((nRead = in.read(cache)) != -1) 
                out.write(cache, 0, nRead);
                out.flush();
            
            out.close();
            in.close();
            data = out.toByteArray();
        
        return data;
    

    /**
     * <p>
     * 二进制数据写文件
     * </p>
     *
     * @param bytes 二进制数据
     * @param filePath 文件生成目录
     */
    public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception 
        InputStream in = new ByteArrayInputStream(bytes);
        File destFile = new File(filePath);
        if (!destFile.getParentFile().exists()) 
            destFile.getParentFile().mkdirs();
        
        destFile.createNewFile();
        OutputStream out = new FileOutputStream(destFile);
        byte[] cache = new byte[CACHE_SIZE];
        int nRead = 0;
        while ((nRead = in.read(cache)) != -1) 
            out.write(cache, 0, nRead);
            out.flush();
        
        out.close();
        in.close();
    


下面是RSA 

import java.util.Collection;
import java.util.Map;

public abstract class Assert 
    public Assert() 
    

    public static void isTrue(boolean expression, String message) 
        if (!expression) 
            throw new IllegalArgumentException(message);
        
    

    public static void isNull(Object object, String message) 
        if (object != null) 
            throw new IllegalArgumentException(message);
        
    

    public static void notNull(Object object, String message) 
        if (object == null) 
            throw new IllegalArgumentException(message);
        
    

    public static void hasLength(String text, String message) 
        if (!hasLength(text)) 
            throw new IllegalArgumentException(message);
        
    

    public static void hasText(String text, String message) 
        if (!hasText(text)) 
            throw new IllegalArgumentException(message);
        
    

    public static void doesNotContain(String textToSearch, String substring, String message) 
        if (hasLength(textToSearch) && hasLength(substring) && textToSearch.contains(substring)) 
            throw new IllegalArgumentException(message);
        
    

    public static void notEmpty(Object[] array, String message) 
        if (array == null || array.length == 0) 
            throw new IllegalArgumentException(message);
        
    

    public static void noNullElements(Object[] array, String message) 
        if (array != null) 
            Object[] var2 = array;
            int var3 = array.length;

            for (int var4 = 0; var4 < var3; ++var4) 
                Object element = var2[var4];
                if (element == null) 
                    throw new IllegalArgumentException(message);
                
            
        

    

    public static void notEmpty(Collection<?> collection, String message) 
        if (isEmpty(collection)) 
            throw new IllegalArgumentException(message);
        
    

    public static void notEmpty(Map<?, ?> map, String message) 
        if (isEmpty(map)) 
            throw new IllegalArgumentException(message);
        
    

    public static void isInstanceOf(Class<?> type, Object obj, String message) 
        notNull(type, "Type to check against must not be null");
        if (!type.isInstance(obj)) 
            throw new IllegalArgumentException((hasLength(message) ? message + " " : "") + "Object of class [" + (obj != null ? obj.getClass().getName() : "null") + "] must be an instance of " + type);
        
    

    public static void isAssignable(Class<?> superType, Class<?> subType, String message) 
        notNull(superType, "Type to check against must not be null");
        if (subType == null || !superType.isAssignableFrom(subType)) 
            throw new IllegalArgumentException(message + subType + " is not assignable to " + superType);
        
    

    private static boolean hasLength(CharSequence str) 
        return str != null && str.length() > 0;
    

    private static boolean hasText(CharSequence str) 
        if (!hasLength(str)) 
            return false;
         else 
            int strLen = str.length();

            for (int i = 0; i < strLen; ++i) 
                if (!Character.isWhitespace(str.charAt(i))) 
                    return true;
                
            

            return false;
        
    

    private static boolean isEmpty(Collection<?> collection) 
        return collection == null || collection.isEmpty();
    

    public static boolean isEmpty(Map<?, ?> map) 
        return map == null || map.isEmpty();
    
import java.nio.charset.Charset;

import org.apache.commons.codec.binary.Base64;

public abstract class Base64Code 
    private static final int CACHE_SIZE = 1024;
    private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
    private static final Base64Delegate delegate = new CommonsCodecBase64Delegate();

    public Base64Code() 
    

    private static void assertSupported() 
        Assert.isTrue(delegate != null, "Apache Commons Codec not found - Base64 encoding not supported````````");
    

    public static byte[] encode(byte[] src) 
        assertSupported();
        return delegate.encode(src);
    

    public static String encodeToString(byte[] src) 
        assertSupported();
        if (src == null) 
            return null;
         else 
            return src.length == 0 ? "" : new String(delegate.encode(src), DEFAULT_CHARSET);
        
    

    public static byte[] decode(byte[] src) 
        assertSupported();
        return delegate.decode(src);
    

    public static byte[] decodeFromString(String src) 
        assertSupported();
        if (src == null) 
            return null;
         else 
            return src.length() == 0 ? new byte[0] : delegate.decode(src.getBytes(DEFAULT_CHARSET));
        
    

    private static class CommonsCodecBase64Delegate implements Base64Delegate 
        private final Base64 base64;

        private CommonsCodecBase64Delegate() 
            this.base64 = new Base64();
        

        public byte[] encode(byte[] src) 
            return this.base64.encode(src);
        

        public byte[] decode(byte[] src) 
            return this.base64.decode(src);
        
    

    private interface Base64Delegate 
        byte[] encode(byte[] var1);

        byte[] decode(byte[] var1);
    
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * RSA加解密方法。
 * 
 * @author yangw
 * @since 1.0.0
 */
public class RSACode 
    
    /** 加解密算法关键字 */
    public static final String KEY_ALGORITHM = "RSA";
    
    /** 公钥关键字 */
    private static final String PUBLIC_KEY = "RSAPublicKey";
    
    /** 私钥关键字 */
    private static final String PRIVATE_KEY = "RSAPrivateKey";
    
    /** *//**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = 117;
    
    /** *//**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = 128;
    /** 
     * 私钥解密。
     * @param data 对应公钥加密后的密文。
     * @param keyBytes 私钥。
     * @return 明文。    
     */      
    public static byte[] decryptByPrivateKey(byte[] data, byte[] keyBytes) throws Exception       
        // 取得私钥      
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);      
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);      
        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);      
     
        // 对数据解密      
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());      
        cipher.init(Cipher.DECRYPT_MODE, privateKey);      
     
        return cipher.doFinal(data);      
           
      
    /** 
     * 公钥解密。
     * @param data 对应私钥加密后的密文。
     * @param keyBytes 公钥。
     * @return 明文。    
     */      
    public static byte[] decryptByPublicKey(byte[] data, byte[] keyBytes) throws Exception 
        // 取得公钥      
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);      
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);      
        Key publicKey = keyFactory.generatePublic(x509KeySpec);      
     
        // 对数据解密      
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());      
        cipher.init(Cipher.DECRYPT_MODE, publicKey);      
     
        return cipher.doFinal(data);      
    
      
    /** 
     * 公钥加密。
     * @param data 明文。
     * @param keyBytes 公钥。
     * @return 密文。     
     */      
    public static byte[] encryptByPublicKey(byte[] data, byte[] keyBytes) throws Exception       
        // 取得公钥      
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);      
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);      
        Key publicKey = keyFactory.generatePublic(x509KeySpec);      
     
        // 对数据加密      
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());      
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);      
     
        return cipher.doFinal(data);      
           
      
    /**   
     * 私钥加密。
     * @param data 明文。
     * @param keyBytes 私钥。
     * @return 密文。      
     */      
    public static byte[] encryptByPrivateKey(byte[] data, byte[] keyBytes) throws Exception           
        // 取得私钥      
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);      
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);      
        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);      
     
        // 对数据加密      
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());      
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);      
     
        return cipher.doFinal(data);      
           
      
    /** 
     * 取得私钥。     
     */      
    public static byte[] getPrivateKey(Map<String, Object> keyMap) throws Exception       
        Key key = (Key) keyMap.get(PRIVATE_KEY);      
        return key.getEncoded();      
           
      
    /** 
     * 取得公钥。      
     */      
    public static byte[] getPublicKey(Map<String, Object> keyMap)       
            throws Exception       
        Key key = (Key) keyMap.get(PUBLIC_KEY);      
        return key.getEncoded();      
           
      
    /**
     * 初始化密钥。    
     */      
    public static Map<String, Object> initKey() throws NoSuchAlgorithmException       
        KeyPairGenerator keyPairGen = KeyPairGenerator .getInstance(KEY_ALGORITHM);      
        keyPairGen.initialize(1024);      
        KeyPair keyPair = keyPairGen.generateKeyPair();      
      
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();    // 公钥                
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();  // 私钥         
        Map<String, Object> keyMap = new HashMap<String, Object>(2);      
     
        keyMap.put(PUBLIC_KEY, publicKey);      
        keyMap.put(PRIVATE_KEY, privateKey);      
        return keyMap;      
    
    
    /**
     * 将密钥用BASE64加密成字符形式。
     */
    public static String encryptBASE64(byte[] encoded)
        if(encoded==null)
            return null;
        
        return Base64Code.encodeToString(encoded);
    
    
    /**
     * 将以BASE64加密的密钥还原为字节数组。
     */
    public static byte[] decryptBASE64(String key) throws IOException
        if(key==null)
            return null;
        
        return Base64Code.decodeFromString(key);
      
    
    
    
    /**
     * 使用私钥进行分段加密
     * @param dataStr 要加密的数据
     * @return 公钥base64字符串
     * @throws Exception
     */
    public static byte[] encryptByPublicKeyToFile(byte[] filebyte,byte[] key)  
            throws Exception   
        //要加密的数据
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);      
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);      
        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);      
        
        // 对数据加密  
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);  
        int inputLen = filebyte.length;  
        ByteArrayOutputStream out = new ByteArrayOutputStream();  
        int offSet = 0;  
        byte[] cache;  
        int i = 0;  
        // 对数据分段加密  
        while (inputLen - offSet > 0)   
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK)   
                cache = cipher.doFinal(filebyte, offSet, MAX_ENCRYPT_BLOCK);  
             else   
                cache = cipher.doFinal(filebyte, offSet, inputLen - offSet);  
              
            out.write(cache, 0, cache.length);  
            i++;  
            offSet = i * MAX_ENCRYPT_BLOCK;  
          
        byte[] encryptedData = out.toByteArray();  
        out.close(); 
        
        return encryptedData;  
     

    /**
     * 使用公钥进行分段解密
     * @param dataStr 使用base64处理过的密文
     * @return 解密后的数据
     * @throws Exception
     */
    public static byte[] decryptByPrivateKeyFile(byte[] dataStr ,byte[] pubKey)  
            throws Exception   
        
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);      
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);      
        Key publicKey = keyFactory.generatePublic(x509KeySpec);   
        
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
        cipher.init(Cipher.DECRYPT_MODE, publicKey);  
        int inputLen = dataStr.length;  
        ByteArrayOutputStream out = new ByteArrayOutputStream();  
        int offSet = 0;  
        byte[] cache;  
        int i = 0;  
        // 对数据分段解密  
        while (inputLen - offSet > 0)   
            if (inputLen - offSet > MAX_DECRYPT_BLOCK)   
                cache = cipher.doFinal(dataStr, offSet, MAX_DECRYPT_BLOCK);  
             else   
                cache = cipher.doFinal(dataStr, offSet, inputLen - offSet);  
              
            out.write(cache, 0, cache.length);  
            i++;  
            offSet = i * MAX_DECRYPT_BLOCK;  
          
        byte[] decryptedData = out.toByteArray();  
        out.close();  
        
        return decryptedData;  
     
    
  

如有疑问请留言!

 

以上是关于非对称加密RSA加密文件的主要内容,如果未能解决你的问题,请参考以下文章

源码基于最优非对称加密填充的RSA加密

非对称加密算法-RSA算法

openssl 非对称加密算法RSA命令详解

Android 中 非对称(RSA)加密和对称(AES)加密

Python使用rsa模块实现非对称加密与解密

jsencrypt实现前端RSA非对称加密解密(vue项目)