非对称加密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加密文件的主要内容,如果未能解决你的问题,请参考以下文章