精华内容
下载资源
问答
  • JAVA文件加密与解密

    千次阅读 2008-03-16 21:50:00
    JAVA文件加密与解密加密算法:DES加密模式:CBC(密码分组链)模式分组填充方式:PKCS#5-Padding名词解释:Ø DES:DES算法是一种对称加密机制,由IBM为美国政府于70年代开发。其入口参数有三个:key、data、mode。 ...

    JAVA文件加密与解密

    加密算法:DES

    加密模式:CBC(密码分组链)模式

    分组填充方式:PKCS#5-Padding

    名词解释:

    Ø        DES

    DES算法是一种对称加密机制,由IBM美国政府于70年代开发。
    其入口参数有三个:keydatamode 其中Key8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;ModeDES的工作方式,有两种:加密或解密。
    实际运用中,密钥只用到了64位中的56位,这样才具有高的安全性。

     

    Ø        CBC模式:

    所有在本文档中描述或涉及的对称块加密算法都使用加密块链接(BCB)模式。这种模式
    的算法需要一个和块的长度一样大小的初始化向量(IV)。使用一个随机产生的IV,防止完
    全一致的和加密算法块尺寸一样长度的第一个明文数据块产生完全一致的密文。
    在数据加密之前,IV和第一个明文块进行XOR运算。然后对于连续的块,在当前的明文
    块加密之前,先和前一个密文块进行一次XOR运算。

     

    Ø        MessageDigest类:

    提供一种安全的单程哈希函数,把任意长度的数据转换成固定长度的哈希值。

    该函数通过update方法把要处理的数据传入MessageDigest类,然后调用digest方法完成转换。此时MessageDigest对象又回到了原来的初始状态。

    这是一个抽像类,应用程序开发人员只需要注意他的几个方法,因为在这个超类中的方法是专门留给愿意把自己的消息摘要算法实现提供出来的密码服务提供者设计的。

     

    Ø        DESKeySpec类:

    DES密钥的的详细说明。

     

    Ø        SecretKeyFactory类:

    一种密钥转换机制,用于密钥(Key)和密钥规范(key specification)之间的互相转换。这个类只作用于秘密密钥(对称密钥)。通过key spefication转换成key.

    这个类会为指定的密码算法产生SecretKeyFactory对象。

     

    Ø        SealedObject类:

    给定一个序列化对象,用SealedObject对象把原始对象封装起来,然后使用一种加密算法用序列化的方式把它的原始内容加密。而加密的内容也可以重新序列化,使用正确的密钥解密。

    原始对象可以通过两种方式还原:

    1.通过一个密码对象(Cipher

    2.通过一个密钥对象(Key

     

    Ø        Cipher类:

    通过传入的一个转换信息字符串,产生一个Cipher对象。

    转换格式:

    1.  “algorithm/mode/padding”

    2.  “algorithm”

     

    如:Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
         
    
      
        
      
    
      
        
      

    Ø         主要异常有:

    NosuchAlgorithmException

    NosuchPaddingException

     

     

     
    展开全文
  • JAVA各种加密与解密方式

    万次阅读 多人点赞 2019-08-30 15:59:43
    之前有兴趣研究了一下java的加密解密的方法,发现市面上有好多种加密解密方式,在这里整理了一下。 目录 1.BASE64加密/解密 2.MD5(Message Digest Algorithm)加密/解密 3.DES(Data Encryption Standard)...

            之前有兴趣研究了一下java的加密与解密的方法,发现市面上有好多种加密解密方式,在这里整理了一下。

    目录

    1.BASE64加密/解密

     

    2.MD5(Message Digest Algorithm)加密

     

    3.DES(Data Encryption Standard)对称加密/解密

     

    4.AES(Advanced Encryption Standard) 加密/解密

     

    5.HMAC(Hash Message Authentication Code,散列消息鉴别码)

     

    6.恺撒加密

     

    7.SHA(Secure Hash Algorithm,安全散列算法)

     

    8.RSA 加密/解密

     

    9.PBE 加密/解密


     

    1.BASE64加密/解密

          Base64 编码是我们程序开发中经常使用到的编码方法,它用 64 个可打印字符来表示二进制数据。这 64 个字符是:小写字母 a-z、大写字母 A-Z、数字 0-9、符号"+"、"/"(再加上作为垫字的"=",实际上是 65 个字符),其他所有符号都转换成这个字符集中的字符。Base64 编码通常用作存储、传输一些二进制数据编码方法,所以说它本质上是一种将二进制数据转成文本数据的方案。

          通常用作对二进制数据进行加密,示例:

    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    public class Base64Util {
    
    	/***
    	 * BASE64解密
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] decryBASE64(String key) throws Exception{
    		return (new BASE64Decoder()).decodeBuffer(key);
    	}
    	
    	/***
    	 * BASE64加密
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static String encryptBASE64(byte[] key) throws Exception{
    		return (new BASE64Encoder()).encode(key);
    	}
    	
    }

     

    2.MD5(Message Digest Algorithm)加密

           MD5 是将任意长度的数据字符串转化成短小的固定长度的值的单向操作,任意两个字符串不应有相同的散列值。因此 MD5 经常用于校验字符串或者文件,因为如果文件的 MD5 不一样,说明文件内容也是不一样的,如果发现下载的文件和给定的 MD5 值不一样,就要慎重使用。

           MD5 主要用做数据一致性验证、数字签名和安全访问认证,而不是用作加密。比如说用户在某个网站注册账户时,输入的密码一般经过 MD5 编码,更安全的做法还会加一层盐(salt),这样密码就具有不可逆性。然后把编码后的密码存入数据库,下次登录的时候把密码 MD5 编码,然后和数据库中的作对比,这样就提升了用户账户的安全性。

        是一种单向加密算法,只能加密不能解密,示例:

    import java.security.MessageDigest;
    
    public class MD5Util {
    
    	public static final String KEY_MD5 = "MD5";  
    	
    	/***
    	 * MD5加密(生成唯一的MD5值)
    	 * @param data
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] encryMD5(byte[] data) throws Exception {
    		MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
    		md5.update(data);
    		return md5.digest();
    	}
    	
    }
    

     

    3.DES(Data Encryption Standard)对称加密/解密

           DES 是一种对称加密算法,所谓对称加密算法就是:加密和解密使用相同密钥的算法。DES 加密算法出自 IBM 的研究,后来被美国政府正式采用,之后开始广泛流传。但近些年使用越来越少,因为 DES 使用 56 位密钥,以现代的计算能力,24 小时内即可被破解。

          顺便说一下 3DES(Triple DES),它是 DES 向 AES 过渡的加密算法,使用 3 条 56 位的密钥对数据进行三次加密。是 DES 的一个更安全的变形。它以 DES 为基本模块,通过组合分组方法设计出分组加密算法。比起最初的 DES,3DES 更为安全。

           使用 Java 实现 DES 加密解密,注意密码长度要是 8 的倍数。加密和解密的 Cipher 构造参数一定要相同,不然会报错。

           数据加密标准算法,和BASE64最明显的区别就是有一个工作密钥,该密钥既用于加密、也用于解密,并且要求密钥是一个长度至少大于8位的字符串,示例:

    import java.security.Key;
    import java.security.SecureRandom;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    
    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    public class DesUtil {
    
    	private static Key key;
    	
    	private static String KEY_STR="myKey";
    	private static String CHARSETNAME="UTF-8";
    	private static String ALGORITHM="DES";
    	
    	
    	static {
    		try {
    			//生成DES算法对象
    			KeyGenerator generator=KeyGenerator.getInstance(ALGORITHM);
    			//运用SHA1安全策略
    			SecureRandom secureRandom=SecureRandom.getInstance("SHA1PRNG");
    			//设置上密钥种子
    			secureRandom.setSeed(KEY_STR.getBytes());
    			//初始化基于SHA1的算法对象
    			generator.init(secureRandom);
    			//生成密钥对象
    			key=generator.generateKey();
    			generator=null;
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		}
    	}
    	
    	
    	/***
    	 * 获取加密的信息
    	 * @param str
    	 * @return
    	 */
    	public static String getEncryptString(String str) {
    		//基于BASE64编码,接收byte[]并转换成String
    		BASE64Encoder encoder = new BASE64Encoder();
    		try {
    			//按utf8编码
    			byte[] bytes = str.getBytes(CHARSETNAME);
    			//获取加密对象
    			Cipher cipher = Cipher.getInstance(ALGORITHM);
    			//初始化密码信息
    			cipher.init(Cipher.ENCRYPT_MODE, key);
    			//加密
    			byte[] doFinal = cipher.doFinal(bytes);
    			//byte[]to encode好的String 并返回
    			return encoder.encode(doFinal);
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		}
    	}
    	
    	
    	/***
    	 * 获取解密之后的信息
    	 * @param str
    	 * @return
    	 */
    	public static String getDecryptString(String str) {
    		BASE64Decoder decoder = new BASE64Decoder();
    		try {
    			//将字符串decode成byte[]
    			byte[] bytes = decoder.decodeBuffer(str);
    			//获取解密对象
    			Cipher cipher = Cipher.getInstance(ALGORITHM);
    			//初始化解密信息
    			cipher.init(Cipher.DECRYPT_MODE, key);
    			//解密
    			byte[] doFial = cipher.doFinal(bytes);
    			
    			return new String(doFial, CHARSETNAME);
    			
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		}
    	}
    	
    }

     

    4.AES(Advanced Encryption Standard) 加密/解密

           高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称 Rijndael 加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的 DES,已经被多方分析且广为全世界所使用。简单说就是 DES 的增强版,比 DES 的加密强度更高。

           AES 与 DES 一样,一共有四种加密模式:电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)。关于加密模式的介绍,推荐这篇文章:高级加密标准AES的工作模式(ECB、CBC、CFB、OFB)

    示例代码:

    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
    public class AESUtil {
    
    	public static final String algorithm = "AES";
    	// AES/CBC/NOPaddin
    	// AES 默认模式
    	// 使用CBC模式, 在初始化Cipher对象时, 需要增加参数, 初始化向量IV : IvParameterSpec iv = new
    	// IvParameterSpec(key.getBytes());
    	// NOPadding: 使用NOPadding模式时, 原文长度必须是8byte的整数倍
    	public static final String transformation = "AES/CBC/NOPadding";
    	public static final String key = "1234567812345678";
    
    	/***
    	 * 加密
    	 * @param original 需要加密的参数(注意必须是16位)
    	 * @return
    	 * @throws Exception
    	 */
    	public static String encryptByAES(String original) throws Exception {
    		// 获取Cipher
    		Cipher cipher = Cipher.getInstance(transformation);
    		// 生成密钥
    		SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);
    		// 指定模式(加密)和密钥
    		// 创建初始化向量
    		IvParameterSpec iv = new IvParameterSpec(key.getBytes());
    		cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
    		// cipher.init(Cipher.ENCRYPT_MODE, keySpec);
    		// 加密
    		byte[] bytes = cipher.doFinal(original.getBytes());
    
    		return Base64Util.encryptBASE64(bytes);
    	}
    
    	/**
    	 * 解密
    	 * @param encrypted 需要解密的参数
    	 * @return
    	 * @throws Exception
    	 */
    	public static String decryptByAES(String encrypted) throws Exception {
    		// 获取Cipher
    		Cipher cipher = Cipher.getInstance(transformation);
    		// 生成密钥
    		SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);
    		// 指定模式(解密)和密钥
    		// 创建初始化向量
    		IvParameterSpec iv = new IvParameterSpec(key.getBytes());
    		cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
    		// cipher.init(Cipher.DECRYPT_MODE, keySpec);
    		// 解密
    		byte[] bytes = cipher.doFinal(Base64Util.decryBASE64(encrypted));
    
    		return new String(bytes);
    	}
    
    }

     

    5.HMAC(Hash Message Authentication Code,散列消息鉴别码)

           使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证,示例:

    import javax.crypto.KeyGenerator;
    import javax.crypto.Mac;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    public class HMACUtil {
    
    	public static final String KEY_MAC = "HmacMD5";  
    	
    	/***
    	 * 初始化HMAC密钥
    	 * @return
    	 * @throws Exception
    	 */
    	public static String initMacKey() throws Exception{
    		
    		KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);
    		SecretKey secreKey = keyGenerator.generateKey();
    		return Base64Util.encryptBASE64(secreKey.getEncoded());
    	}
    	
    	/**
    	 * HMAC加密
    	 * @param data
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] encryHMAC(byte[] data, String key) throws Exception{
    		SecretKey secreKey = new SecretKeySpec(Base64Util.decryBASE64(key), KEY_MAC);
    		Mac mac = Mac.getInstance(secreKey.getAlgorithm());
    		mac.init(secreKey);
    		return mac.doFinal();
    	}
    	
    }

     

    6.恺撒加密

    • 在密码学中,恺撒密码是一种最简单并且最广为人知的加密技术。

    • 它是一种替换加密的技术,明文中的所欲字母都在字母表上向后(或向前)按照一个固定的数目进行偏移后被替换成密文。

    • 例如:当偏移量是3的时候,所有的字母A将被替换成D,B变成E,以此类推。

    • 这个加密方法是以恺撒的名字命名的,当年恺撒曾用此方法与其将军们进行联系。

    • 恺撒密码通常被座位其他更复杂的加密方法中的一个步骤。

    示例代码:

    public class KaisaUtil {
    
    	/***
    	 * 使用凯撒加密方式加密数据
    	 * @param orignal 原文
    	 * @param key 密钥
    	 * @return 加密后的字符
    	 */
    	private static String encryptKaisa(String orignal, int key) {
    		//将字符串转换为数组
    		char[] chars = orignal.toCharArray();
    		StringBuffer buffer = new StringBuffer();
    		//遍历数组
    		for(char aChar : chars) {
    			//获取字符的ASCII编码
    			int asciiCode = aChar;
    			//偏移数据
    			asciiCode += key;
    			//将偏移后的数据转为字符
    			char result = (char)asciiCode;
    			//拼接数据
    			buffer.append(result);
    		}
    		return buffer.toString();
    	}
    	
    	/**
    	 * 使用凯撒加密方式解密数据
    	 *
    	 * @param encryptedData :密文
    	 * @param key           :密钥
    	 * @return : 源数据
    	 */
    	private static String decryptKaiser(String encryptedData, int key) {
    	    // 将字符串转为字符数组
    	    char[] chars = encryptedData.toCharArray();
    	    StringBuilder sb = new StringBuilder();
    	    // 遍历数组
    	    for (char aChar : chars) {
    	        // 获取字符的ASCII编码
    	        int asciiCode = aChar;
    	        // 偏移数据
    	        asciiCode -= key;
    	        // 将偏移后的数据转为字符
    	        char result = (char) asciiCode;
    	        // 拼接数据
    	        sb.append(result);
    	    }
    
    	    return sb.toString();
    	}
    	
    	
    	public static void main(String[] args) {
    		String str = "open fire";
    		String encode = encryptKaisa(str, 3);
    		System.out.println("加密后:"+encode);
    		
    		String decode = decryptKaiser(encode, 3);
    		System.out.println("解密后:"+decode);
    		
    	}
    	
    }

     

    7.SHA(Secure Hash Algorithm,安全散列算法)

            SHA全名叫做安全散列算法,是FIPS所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的机率很高。

            数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域,示例:

    import java.security.MessageDigest;
    
    public class SHAUtil {
    
    	public static final String KEY_SHA = "SHA";  
        public static final String ALGORITHM = "SHA-256";
    	
    	/***
    	 * SHA加密(比MD5更安全)
    	 * @param data
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] encryptSHA(byte[] data) throws Exception{
    		MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
    		sha.update(data);
    		return sha.digest();
    	}
    	
    	
    	public static String SHAEncrypt(final String content) {
            try {
                MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
                byte[] sha_byte = sha.digest(content.getBytes());
                StringBuffer hexValue = new StringBuffer();
                for (byte b : sha_byte) {
                    //将其中的每个字节转成十六进制字符串:byte类型的数据最高位是符号位,通过和0xff进行与操作,转换为int类型的正整数。
                    String toHexString = Integer.toHexString(b & 0xff);
                    hexValue.append(toHexString.length() == 1 ? "0" + toHexString : toHexString);
                }
                return hexValue.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
           return "";
        }
    
    
        
        //SHA-256加密
        public static String SHA256Encrypt(String sourceStr) {
            MessageDigest md = null;
            try {
                md = MessageDigest.getInstance(ALGORITHM);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            if (null != md) {
                md.update(sourceStr.getBytes());
                String digestStr = getDigestStr(md.digest());
                return digestStr;
            }
    
            return null;
        }
    
        private static String getDigestStr(byte[] origBytes) {
            String tempStr = null;
            StringBuilder stb = new StringBuilder();
            for (int i = 0; i < origBytes.length; i++) {
                tempStr = Integer.toHexString(origBytes[i] & 0xff);
                if (tempStr.length() == 1) {
                    stb.append("0");
                }
                stb.append(tempStr);
    
            }
            return stb.toString();
        }
    }

     

    8.RSA 加密/解密

           RSA算法是一种非对称加密算法,所谓非对称就是该算法需要一对密钥,若使用其中一个加密,则需要用另一个才能解密。目前它是最有影响力和最常用的公钥加密算法,能够抵抗已知的绝大多数密码攻击。从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。

           该算法基于一个的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。由于进行的都是大数计算,RSA 最快的情况也比 DES 慢上好几倍,比对应同样安全级别的对称密码算法要慢 1000 倍左右。所以 RSA 一般只用于少量数据加密,比如说交换对称加密的密钥。

    使用 RSA 加密主要有这么几步:生成密钥对、公开公钥、公钥加密私钥解密、私钥加密公钥解密。

    示例代码:

    import com.sun.org.apache.xml.internal.security.utils.Base64;
    import javax.crypto.Cipher;
    
    import org.apache.commons.io.FileUtils;
    
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.nio.charset.Charset;
    import java.security.*;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    public class RsaUtil {
    
    	/**
         * 生成密钥对并保存在本地文件中
         *
         * @param algorithm : 算法
         * @param pubPath   : 公钥保存路径
         * @param priPath   : 私钥保存路径
         * @throws Exception
         */
        private static void generateKeyToFile(String algorithm, String pubPath, String priPath) throws Exception {
            // 获取密钥对生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
            // 获取密钥对
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            // 获取公钥
            PublicKey publicKey = keyPair.getPublic();
            // 获取私钥
            PrivateKey privateKey = keyPair.getPrivate();
            // 获取byte数组
            byte[] publicKeyEncoded = publicKey.getEncoded();
            byte[] privateKeyEncoded = privateKey.getEncoded();
            // 进行Base64编码
            String publicKeyString = Base64.encode(publicKeyEncoded);
            String privateKeyString = Base64.encode(privateKeyEncoded);
            // 保存文件
            FileUtils.writeStringToFile(new File(pubPath), publicKeyString, Charset.forName("UTF-8"));
            FileUtils.writeStringToFile(new File(priPath), privateKeyString, Charset.forName("UTF-8"));
    
        }
    
        /**
         * 从文件中加载公钥
         *
         * @param algorithm : 算法
         * @param filePath  : 文件路径
         * @return : 公钥
         * @throws Exception
         */
        private static PublicKey loadPublicKeyFromFile(String algorithm, String filePath) throws Exception {
            // 将文件内容转为字符串
            String keyString = FileUtils.readFileToString(new File(filePath), Charset.forName("UTF-8"));
    
            return loadPublicKeyFromString(algorithm, keyString);
    
        }
    
        /**
         * 从字符串中加载公钥
         *
         * @param algorithm : 算法
         * @param keyString : 公钥字符串
         * @return : 公钥
         * @throws Exception
         */
        private static PublicKey loadPublicKeyFromString(String algorithm, String keyString) throws Exception {
            // 进行Base64解码
            byte[] decode = Base64.decode(keyString);
            // 获取密钥工厂
            KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
            // 构建密钥规范
            X509EncodedKeySpec keyspec = new X509EncodedKeySpec(decode);
            // 获取公钥
            return keyFactory.generatePublic(keyspec);
    
        }
    
        /**
         * 从文件中加载私钥
         *
         * @param algorithm : 算法
         * @param filePath  : 文件路径
         * @return : 私钥
         * @throws Exception
         */
        private static PrivateKey loadPrivateKeyFromFile(String algorithm, String filePath) throws Exception {
            // 将文件内容转为字符串
            String keyString = FileUtils.readFileToString(new File(filePath), Charset.forName("UTF-8"));
            return loadPrivateKeyFromString(algorithm, keyString);
    
        }
    
        /**
         * 从字符串中加载私钥
         *
         * @param algorithm : 算法
         * @param keyString : 私钥字符串
         * @return : 私钥
         * @throws Exception
         */
        private static PrivateKey loadPrivateKeyFromString(String algorithm, String keyString) throws Exception {
            // 进行Base64解码
            byte[] decode = Base64.decode(keyString);
            // 获取密钥工厂
            KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
            // 构建密钥规范
            PKCS8EncodedKeySpec keyspec = new PKCS8EncodedKeySpec(decode);
            // 生成私钥
            return keyFactory.generatePrivate(keyspec);
    
        }
    
        /**
         * 使用密钥加密数据
         *
         * @param algorithm      : 算法
         * @param input          : 原文
         * @param key            : 密钥
         * @param maxEncryptSize : 最大加密长度(需要根据实际情况进行调整)
         * @return : 密文
         * @throws Exception
         */
        private static String encrypt(String algorithm, String input, Key key, int maxEncryptSize) throws Exception {
            // 获取Cipher对象
            Cipher cipher = Cipher.getInstance(algorithm);
            // 初始化模式(加密)和密钥
            cipher.init(Cipher.ENCRYPT_MODE, key);
            // 将原文转为byte数组
            byte[] data = input.getBytes();
            // 总数据长度
            int total = data.length;
            // 输出流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            decodeByte(maxEncryptSize, cipher, data, total, baos);
            // 对密文进行Base64编码
            return Base64.encode(baos.toByteArray());
    
        }
    
        /**
         * 解密数据
         *
         * @param algorithm      : 算法
         * @param encrypted      : 密文
         * @param key            : 密钥
         * @param maxDecryptSize : 最大解密长度(需要根据实际情况进行调整)
         * @return : 原文
         * @throws Exception
         */
        private static String decrypt(String algorithm, String encrypted, Key key, int maxDecryptSize) throws Exception {
            // 获取Cipher对象
            Cipher cipher = Cipher.getInstance(algorithm);
            // 初始化模式(解密)和密钥
            cipher.init(Cipher.DECRYPT_MODE, key);
            // 由于密文进行了Base64编码, 在这里需要进行解码
            byte[] data = Base64.decode(encrypted);
            // 总数据长度
            int total = data.length;
            // 输出流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
    
            decodeByte(maxDecryptSize, cipher, data, total, baos);
            // 输出原文
            return baos.toString();
    
        }
    
        /**
         * 分段处理数据
         *
         * @param maxSize : 最大处理能力
         * @param cipher  : Cipher对象
         * @param data    : 要处理的byte数组
         * @param total   : 总数据长度
         * @param baos    : 输出流
         * @throws Exception
         */
        private static void decodeByte(int maxSize, Cipher cipher, byte[] data, int total, ByteArrayOutputStream baos) throws Exception {
            // 偏移量
            int offset = 0;
            // 缓冲区
            byte[] buffer;
            // 如果数据没有处理完, 就一直继续
            while (total - offset > 0) {
                // 如果剩余的数据 >= 最大处理能力, 就按照最大处理能力来加密数据
                if (total - offset >= maxSize) {
                    // 加密数据
                    buffer = cipher.doFinal(data, offset, maxSize);
                    // 偏移量向右侧偏移最大数据能力个
                    offset += maxSize;
                } else {
                    // 如果剩余的数据 < 最大处理能力, 就按照剩余的个数来加密数据
                    buffer = cipher.doFinal(data, offset, total - offset);
                    // 偏移量设置为总数据长度, 这样可以跳出循环
                    offset = total;
                }
                // 向输出流写入数据
                baos.write(buffer);
            }
        }
    }

      加密算法的安全级别(Security Level of Cryptographic Algorithms):

    安全级别 
    (Security Level)
    工作因素 
    (Work Factor)
    算法 
    (Algorithms)
    薄弱(Weak)O(240)DESMD5
    传统(Legacy)O(264)RC4SHA-1
    基准(Baseline)O(280)3DES
    标准(Standard)O(2128)AES-128SHA-256
    较高(High)O(2192)AES-192SHA-384
    超高(Ultra)O(2256)AES-256SHA-512

     

    9.PBE 加密/解密

         PBE是一种基于口令的加密算法,使用口令代替其他对称加密算法中的密钥,其特点在于口令由用户自己掌管,不借助任何物理媒体;采用随机数(这里我们叫做盐)杂凑多重加密等方法保证数据的安全性。

         PBE算法是对称加密算法的综合算法,常见算法PBEWithMD5AndDES,使用MD5和DES算法构建了PBE算法。将盐附加在口令上,通过消息摘要算法经过迭代获得构建密钥的基本材料,构建密钥后使用对称加密算法进行加密解密。

    算法/密钥长度/默认密钥长度:

    1.PBEWithMD5AndDES/56/56
    2.PBEWithMD5AndTripleDES/112,168/168
    3.PBEWithSHA1AndDESede/112,168/168
    4.PBEWithSHA1AndRC2_40/40 to 1024/128

    工作模式:CBC
    填充方式:PKCS5Padding

    示例代码:

    import java.security.Key;
    import java.security.SecureRandom;
    
    import javax.crypto.Cipher;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.PBEKeySpec;
    import javax.crypto.spec.PBEParameterSpec;
    
    public class PBEUtil {
    
    	public static final String ALGORITHM = "PBEWITHMD5andDES";
    	
    	public static final int ITERATION_COUNT = 100;
    	
    	
    	public static byte[] initSalt() throws Exception{
    		//实例化安全随机数
    		SecureRandom random = new SecureRandom();
    		return random.generateSeed(8);
    	}
    	
    	/***
    	 * 转换密钥
    	 * @param password 密码
    	 * @return 密钥
    	 * @throws Exception
    	 */
    	private static Key toKey(String password) throws Exception{
    		//密钥材料
    		PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
    		//实例化
    		SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
    		//生成密钥
    		return factory.generateSecret(keySpec);
    	}
    	
    	/***
    	 * 加密
    	 * @param data 待加密数据
    	 * @param password 密钥
    	 * @param salt
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] encrypt(byte[] data, String password, byte[] salt) throws Exception{
    		//转换密钥
    		Key key = toKey(password);
    		//实例化PBE参数材料
    		PBEParameterSpec spec = new PBEParameterSpec(salt, ITERATION_COUNT);
    		//实例化
    		Cipher cipher = Cipher.getInstance(ALGORITHM);
    		//初始化
    		cipher.init(Cipher.ENCRYPT_MODE, key, spec);
    		return cipher.doFinal(data);
    	}
    	
    	
    	/***
    	 * 解密
    	 * @param data 待解密数据
    	 * @param password 密钥
    	 * @param salt
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] decrypt(byte[] data, String password, byte[] salt) throws Exception{
    		//转换密钥
    		Key key = toKey(password);
    		//实例化PBE参数材料
    		PBEParameterSpec spec = new PBEParameterSpec(salt, ITERATION_COUNT);
    		//实例化
    		Cipher cipher = Cipher.getInstance(ALGORITHM);
    		//初始化  
            cipher.init(Cipher.DECRYPT_MODE, key, spec);
    		//执行操作  
    		return cipher.doFinal(data);  
    	}
    	
    	
    	private static String showByteArray(byte[] data) {
    		if(null == data) {
    			return null;
    		}
    		StringBuilder sb = new StringBuilder();
    		for(byte b : data) {
    			sb.append(b).append(",");
    		}
    		sb.deleteCharAt(sb.length()-1);
    		sb.append("");
    		return sb.toString();
    	}
    	
    	
    	public static void main(String[] args) throws Exception{
    		byte[] salt = initSalt();
    		System.out.println("salt:"+showByteArray(salt));
    		String password = "1111";
    		System.out.println("口令:"+password);
    		String data = "PBE数据";
    		System.out.println("加密前数据:String:"+data);
    		System.out.println("加密前数据:byte[]:"+showByteArray(data.getBytes()));
    		
    		byte[] encryptData = encrypt(data.getBytes(), password, salt);
    		System.out.println("加密后数据:byte[]:"+showByteArray(encryptData));
    		
    		byte[] decryptData = decrypt(encryptData, password, salt);
            System.out.println("解密后数据: byte[]:"+showByteArray(decryptData));
            System.out.println("解密后数据: string:"+new String(decryptData));
    	}
    }

     

    本篇文章参考了以下两位的文章,感谢

    https://www.jianshu.com/p/26adec49cb34

    https://www.jianshu.com/p/213d69ac27b3

    展开全文
  • des加密算法(js+java加密与解密结果相同

    千次下载 热门讨论 2014-01-17 14:08:25
    des加密算法(js+java)加密解密结果相同 包含三个文件 : des.js des.html ,用于实现前端脚本的加密... des.java 用于后台的加密解密操作; 项目中正好用到,已经过验证,两个加密解密结果相同,分享给大家!
  • java文件加密解密

    2014-11-12 12:59:39
    Java文件加密解密 本软件的制作原理是:文件的读写,拷贝。通过从一个文件中读取字节,在写入时加上一个偏移量来实现加密功能,解密则返过来,即减去一个相同的偏移量。 本软件的优点是:1.实现了大文件的加密,...

    Java文件加密和解密

    本软件的制作原理是:文件的读写,拷贝。通过从一个文件中读取字节,在写入时加上一个偏移量来实现加密功能,解密则返过来,即减去一个相同的偏移量。

    本软件的优点是:1.实现了大文件的加密,对视频,歌曲,文本文件等都是可以的。2.大文件加密的时候,加了线程处理,不会造成按钮按下去后,要到加密或解密完成时才能弹起,给用户造成不便。3.软件的基本健壮性已经实现,加密或解密完成时,会弹出一个提示窗口,若没弹出,则代表没有完成加密或解密。4,.软件是使用了2个下拉框来实现的,方便用户使用,输入的加密的码的范围是00~99,一共100个,即破解率为1%。5.本软件是把用户的加密的码写入了用户的文件中,待到用户解密时,就会获取那个加入的加密的码,与用户输入的解密的码相比较,这实现了多个文件的压缩。6.本软件新加了进度条,能反映加密过程。

    本软件有待升级的地方:1.加密解密大文件是速度较慢,请耐心等待。2.加密或解密是针对原文件的,若是加密失败,原文件会被破坏,用户使用时,一定要先备份,先试一下加密和解密是否成功,若是成功了,再对原文件加密。

     

    接下来附上源代码:

    这是加密解密和进度条界面的代码:

    package ctong17;
    
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.File;
    import java.io.FileInputStream;
    
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JFileChooser;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JProgressBar;
    import javax.swing.JTextField;
    
    
    
    public class FileLock {
    //		private static int rate;
    		private static JProgressBar jpr = new JProgressBar();
    	    private static FileInputStream fis; 
    	    private static JComboBox box,box1,box2,box3;
    		private static File f,file,file1 ;
    		private static JTextField jt1,jt3;   
    		/**
    		 * 文件加密界面
    		 */
    		public static void init_ya(){
    	    	final JFrame jf_ya=new JFrame();
    	    	jf_ya.setTitle("文件加密系统");
    	    	jf_ya.setLocation(530,175);
    	    	jf_ya.setResizable(false);
    	    	jf_ya.setSize(300, 300);
    	    	jf_ya.setIconImage(new ImageIcon("4.gif").getImage());//添加方框的图标
    	    	
    	    	JPanel center = new JPanel();
    	    	center.setLayout(new GridLayout(2,3));
    	    	JPanel south = new JPanel();
    	    	
    	    	JButton btn_ya = new JButton("开始加密(Enter)");
    	    	JButton btn_fanhui = new JButton("返回(Backspace)");
    	    	JButton btn_xuanze = new JButton("选择");
    	    	//这是下拉框
    	    	box =new JComboBox();
    	    	box.addItem("0");
    	    	box.addItem("1");
    	    	box.addItem("2");
    	    	box.addItem("3");
    	    	box.addItem("4");
    	    	box.addItem("5");
    	    	box.addItem("6");
    	    	box.addItem("7");
    	    	box.addItem("8");
    	    	box.addItem("9");
    	    	box1 =new JComboBox();
    	    	box1.addItem("0");
    	    	box1.addItem("1");
    	    	box1.addItem("2");
    	    	box1.addItem("3");
    	    	box1.addItem("4");
    	    	box1.addItem("5");
    	    	box1.addItem("6");
    	    	box1.addItem("7");
    	    	box1.addItem("8");
    	    	box1.addItem("9");
    	    	
    	    	jt1 = new JTextField();
    	    	
    	    	JLabel jl1 = new JLabel("选择加密文件:",JLabel.CENTER);
    	    	JLabel jl2 = new JLabel("加密码:",JLabel.CENTER);
    	    	JLabel jl3=new JLabel(new ImageIcon("6.gif"));
    	    	jl3.setPreferredSize(new Dimension(30,180));
    	    	
    	    	center.add(jl1);
    	    	center.add(jt1);
    	    	center.add(btn_xuanze);
    	    	center.add(jl2);
    	    	center.add(box);
    	    	center.add(box1);
    	    	south.add(btn_ya);
    	    	south.add(btn_fanhui);
    	    	
    	    	jf_ya.add(jl3,BorderLayout.NORTH);
    	    	jf_ya.add(center,BorderLayout.CENTER);
    	    	jf_ya.add(south,BorderLayout.SOUTH);
    	    	
    	    	jf_ya.setVisible(true);
    	    	//返回按钮
    	    	btn_fanhui.addActionListener(new ActionListener() {
    	    		
    	    		public void actionPerformed(ActionEvent e) {
    	    			jf_ya.setVisible(false);
    	    			init_First();
    	    		}
    	    	});
    	    	//选择文件按钮
    	    	btn_xuanze.addActionListener(new ActionListener() {
    	    		
    	    		public void actionPerformed(ActionEvent e) {
    	    			//打开文件选择器
    	    			JFileChooser jc = new JFileChooser();
    	    			jc.showOpenDialog(jf_ya);
    	    			file = jc.getSelectedFile();
    	    			
    	    			//获取文件的绝对路径
    	    			jt1.setText(file.getAbsolutePath());
    	    		}
    	    	});
    	    	//加密按钮
    	    	btn_ya.addActionListener(new ActionListener() {
    				public void actionPerformed(ActionEvent e) {
    					//这个文件是中转文件,用来缓冲的
    //					f = new File(file.toURI());
    					f= new File("1.txt"); 
    					//线程,处理加密文件过程
    					YaThread yt = new YaThread(jpr, file,f, jt1, box, box1);
    					yt.start();
    					
    				}
    			});
    	    }
    	    /*
    	     * 这是主的界面
    	     */
    	    public static void init_First(){
    	    	final JFrame jf_first = new JFrame("文件加密系统");
    	    	
    	    	jf_first.setSize(300,300);
    	    	jf_first.setLocation(530,175);
    	    	jf_first.setResizable(false);
    	    	jf_first.setDefaultCloseOperation(3);
    	    	jf_first.setIconImage(new ImageIcon("4.gif").getImage());//添加方框的图标
    	    	
    	    	JPanel pa = new JPanel();
    	    	pa.setLayout(new GridLayout(1,2));
    	    	JButton btn_ya = new JButton("加密");
    	    	JButton btn_jie = new JButton("解密");
    	    	
    	    	JLabel jl3=new JLabel(new ImageIcon("1.gif"));
    	    	jl3.setPreferredSize(new Dimension(30,240));
    	    	
    	    	pa.add(btn_ya);
    	    	pa.add(btn_jie);
    	    	
    	    	jf_first.add(jl3,BorderLayout.NORTH);
    	    	jf_first.add(pa,BorderLayout.CENTER);
    	    	
    	    	jf_first.setVisible(true);
    	    	//解密按钮
    	    	btn_jie.addActionListener(new ActionListener() {
    				public void actionPerformed(ActionEvent e) {
    					init_jie();
    					jf_first.setVisible(false);
    				}
    			});
    	    	//加密按钮
    	    	btn_ya.addActionListener(new ActionListener() {
    	    		public void actionPerformed(ActionEvent e) {
    	    			init_ya();
    	    			
    	    			jf_first.setVisible(false);
    	    		}
    	    	});
    	    }
    	    /*
    	     * 这是解密的界面
    	     */
    	    public static void init_jie(){
    	    	final JFrame jf_jie=new JFrame("文件解密系统");
    	    	
    	    	jf_jie.setLocation(530,175);
    	    	jf_jie.setResizable(false);
    	    	jf_jie.setSize(300, 300);
    	    	jf_jie.setIconImage(new ImageIcon("4.gif").getImage());//添加方框的图标
    	    	
    	    	JPanel center = new JPanel();
    	    	//中间面板设置表格布局
    	    	center.setLayout(new GridLayout(2,3));
    	    	JPanel south = new JPanel();
    	    	
    	    	JButton btn_jie = new JButton("开始解密(Enter)");
    	    	JButton btn_fanhui = new JButton("返回(Backspace)");
    	    	JButton btn_xuanze = new JButton("选择");
    	    	//这是下拉框
    	    	box2 =new JComboBox();
    	    	box2.addItem("0");
    	    	box2.addItem("1");
    	    	box2.addItem("2");
    	    	box2.addItem("3");
    	    	box2.addItem("4");
    	    	box2.addItem("5");
    	    	box2.addItem("6");
    	    	box2.addItem("7");
    	    	box2.addItem("8");
    	    	box2.addItem("9");
    	    	box3 =new JComboBox();
    	    	box3.addItem("0");
    	    	box3.addItem("1");
    	    	box3.addItem("2");
    	    	box3.addItem("3");
    	    	box3.addItem("4");
    	    	box3.addItem("5");
    	    	box3.addItem("6");
    	    	box3.addItem("7");
    	    	box3.addItem("8");
    	    	box3.addItem("9");
    	    	
    	    	 jt3 = new JTextField(6);
    	    	 
    	    	JLabel jl1 = new JLabel("选择解密文件:",JLabel.CENTER);
    	    	JLabel jl2 = new JLabel("解密码:",JLabel.CENTER);
    	    	JLabel jl3=new JLabel(new ImageIcon("8.gif"));
    	    	jl3.setPreferredSize(new Dimension(30,180));
    	    	
    	    	center.add(jl1);
    	    	center.add(jt3);
    	    	center.add(btn_xuanze);
    	    	center.add(jl2);
    	    	center.add(box2);
    	    	center.add(box3);
    	    	south.add(btn_jie);
    	    	south.add(btn_fanhui);
    	    	
    	    	jf_jie.add(jl3,BorderLayout.NORTH);
    	    	jf_jie.add(center,BorderLayout.CENTER);
    	    	jf_jie.add(south,BorderLayout.SOUTH);
    	    	
    	    	jf_jie.setVisible(true);
    	    	//选择文件的按钮
    	    	btn_xuanze.addActionListener(new ActionListener() {
    	    		public void actionPerformed(ActionEvent e) {
    	    			//文件选择器,选择解密文件
    	    			JFileChooser jc = new JFileChooser();
    	    			jc.showOpenDialog(jf_jie);
    	    			file1 = jc.getSelectedFile();
    	    			//获取文件的绝对路径,显示
    	    			jt3.setText(file1.getAbsolutePath());
    	    			
    	    		}
    	    	});
    	    	//返回按钮
    	    	btn_fanhui.addActionListener(new ActionListener() {
    	    		public void actionPerformed(ActionEvent e) {
    	    			jf_jie.setVisible(false);
    	    			init_First();
    	    		}
    	    	});
    	    	//解密按钮
    	    	btn_jie.addActionListener(new ActionListener() {
    				public void actionPerformed(ActionEvent e) {
    					//线程,用来处理解密文件的过程
    					JieThread jt = new JieThread(jpr, fis, f, jt3, box2, box3,file1);
    					jt.start();
    				}
    				});
    	    }
    //	    public FileLock(int rate){
    //	    	this.rate=rate;
    //	    }
    	    //进度条界面
    	    public static void JProgress_Bar(){
    			JFrame jf = new JFrame("进度");
    			jf.setSize(300,90);
    			jf.setLocation(530,435);
    			jf.setAlwaysOnTop(true);
    			jpr.setMinimum(0);
    			jpr.setPreferredSize(new Dimension(200,30));
    			jpr.setBackground(Color.WHITE);
    			jpr.setForeground(Color.BLUE);
    			jpr.setStringPainted(true);
    			jf.setLayout(new FlowLayout());
    			jf.add(jpr);
    			jf.setVisible(true);
    			
    		}
    	    
    	public static void main(String[] args) {
    		init_First();
    	}
    	
    		
    
    }
    
    

     以下分别是加密,解密的线程(用来处理加密 解密):

     

    package ctong17;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    
    import javax.swing.JComboBox;
    import javax.swing.JOptionPane;
    import javax.swing.JProgressBar;
    import javax.swing.JTextField;
    
    public class YaThread extends Thread{
    	private static JProgressBar jpr;
    	private static int rate=0;
    	private static int count=0,count1=0;
    	private File f,file;
    	private static JTextField jt1;
    	private static FileInputStream fis; 
        private static FileOutputStream fos; 
        private static JComboBox box,box1;
    	private static int t1,t2;
    	//构造函数,把需要的数据传输过来
    	public YaThread(JProgressBar jpr,File file,File f,JTextField jt1,JComboBox box,JComboBox box1){
    		this.jpr=jpr;
    		this.file=file;
    		this.f=f;
    		this.jt1=jt1;
    		this.box=box;
    		this.box1=box1;
    	}
    	public void run(){
    		if(jt1.getText().isEmpty()) JOptionPane.showMessageDialog(null, "请选择文件!");
    		else{
    			new FileLock().JProgress_Bar();
    			count = (int)file.length();
    			count1 = count;
    			jpr.setMaximum(2*count1);
    			jiami(jt1.getText(),f.getAbsolutePath());
    			
    			copy(f.getAbsolutePath(),jt1.getText());
    			
    			//删除缓冲的文件
    			f.delete();
    			JOptionPane.showMessageDialog(null, "加密完成!");
    		}
    	}
    	public static void jiami(String filename,String newname ){
    		try {
    			final int t=count1;
    			t1=Integer.parseInt(box.getSelectedItem().toString());
    			t2=Integer.parseInt(box1.getSelectedItem().toString());
    			
    			fis =new FileInputStream(filename);
    			fos =new FileOutputStream(newname);
    			//文件拷贝过程
    			//把用户输入的加密的码先保存在文件中,以便在以后解密时获取其的加密的码,与用户输入的解密的码比较
    			fos.write(t1);
    			fos.write(t2);
    			int n =fis.read();
    			
    			while (n !=-1){
    				//可以进行文件的加密和解密
    				fos.write(n+10*t1+t2);
    				rate=t-(--count);
    				jpr.setValue(rate);
    				n=fis.read();
    				
    			}
    			
    			fis.close();
    			fos.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	//文件拷贝方法
    	public static void copy(String from,String to){
    		try {
    			fis =new FileInputStream(from);
    			fos =new FileOutputStream(to);
    			//文件拷贝过程
    			int n =fis.read();
    			while (n !=-1){
    				//可以进行文件的加密和解密
    				fos.write(n);
    				jpr.setValue(rate+(++count));
    				n=fis.read();
    				
    			}
    			
    			fis.close();
    			fos.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    
    

     ************************************

     

    package ctong17;
    
    import java.awt.HeadlessException;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    import javax.swing.JComboBox;
    import javax.swing.JOptionPane;
    import javax.swing.JProgressBar;
    import javax.swing.JTextField;
    
    public class JieThread extends Thread{
    	private static JProgressBar jpr;
    	private static int rate=0;
    	private static int count=0,count1=0;
    	private static FileInputStream fis; 
        private static FileOutputStream fos; 
        private static JComboBox box2,box3;
    	private static int t3,t4;
    	private File f,file1;
    	private static JTextField jt3;    
    	public JieThread(JProgressBar jpr,FileInputStream fis,File f,JTextField jt3,JComboBox box2,JComboBox box3,File file1){
    		this.jpr=jpr;
    		this.fis=fis;
    		this.f=f;
    		this.jt3=jt3;
    		this.box2=box2;
    		this.box3=box3;
    		this.file1=file1;
    		
    	}
    	public void run(){
    		if(jt3.getText().isEmpty()) JOptionPane.showMessageDialog(null, "请选择文件!");
    		else{
    			
    			try {
    				fis = new FileInputStream(jt3.getText());
    				//从文件中读取加密的码,与解密的码比较
    				if(fis.read()==Integer.parseInt(box2.getSelectedItem().toString())&&fis.read()==Integer.parseInt(box3.getSelectedItem().toString())){
    					//创建缓冲文件,如果各位同志没有F盘请自改,之所以不改为C盘是因为一般的用户机子里的C盘不允许访问
    
    					new FileLock().JProgress_Bar();
    					f= new File("1.txt"); 
    //					f= new File(file1.toURI()); 
    					count = (int)file1.length();
    					count1 = count;
    					jpr.setMaximum(2*count1-4);
    					jiemi(jt3.getText(),f.getAbsolutePath());
    					
    					copy(f.getAbsolutePath(),jt3.getText());
    					
    					//删除缓冲文件
    					f.delete();
    					JOptionPane.showMessageDialog(null, "解密完成!");
    				}else JOptionPane.showMessageDialog(null, "解密码不正确,请重新输入");
    			} catch (NumberFormatException e1) {
    				e1.printStackTrace();
    			} catch (HeadlessException e1) {
    				e1.printStackTrace();
    			} catch (IOException e1) {
    				e1.printStackTrace();
    			}
    		}
    	}
    	public static void jiemi(String filename,String newname){
    		try {
    			final int t=count1;	
    			t3=Integer.parseInt(box2.getSelectedItem().toString());
    			t4=Integer.parseInt(box3.getSelectedItem().toString());
    			fis =new FileInputStream(filename);
    			fos =new FileOutputStream(newname);
    			//文件拷贝过程
    			//跳过2个字节,即一个字的大小
    			fis.skip(2);
    			int n =fis.read();
    			while (n !=-1){
    				//可以进行文件的加密和解密
    				fos.write(n-10*t3-t4);
    				rate=t-(--count);
    				jpr.setValue(rate);
    				n=fis.read();
    				
    			}
    			fis.close();
    			fos.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	public static void copy(String from,String to){
    		try {
    			fis =new FileInputStream(from);
    			fos =new FileOutputStream(to);
    			//文件拷贝过程
    			int n =fis.read();
    			while (n !=-1){
    				//可以进行文件的加密和解密
    				fos.write(n);
    				jpr.setValue(rate+(++count));
    				n=fis.read();
    				
    			}
    			fis.close();
    			fos.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    
    

     以下是操作的图片:



     
     

     

     
     

     

     

    文件加密的可执行程序已发,感兴趣的同学可以下载!欢迎留言,我会积极采纳你们的宝贵建议或意见。

    展开全文
  • JAVA各种加密与解密算法【转载】

    千次阅读 2020-04-23 09:07:17
            之前有兴趣研究了一下java的加密解密的方法,发现市面上有好多种加密解密方式,在这里整理了一下。 目录 1.BASE64加密/解密 &...

            之前有兴趣研究了一下java的加密与解密的方法,发现市面上有好多种加密解密方式,在这里整理了一下。

    目录

    1.BASE64加密/解密

     

    2.MD5(Message Digest Algorithm)加密/解密

     

    3.DES(Data Encryption Standard)对称加密/解密

     

    4.AES(Advanced Encryption Standard) 加密/解密

     

    5.HMAC(Hash Message Authentication Code,散列消息鉴别码)

     

    6.恺撒加密

     

    7.SHA(Secure Hash Algorithm,安全散列算法)

     

    8.RSA 加密/解密

     

    9.PBE 加密/解密


     

    1.BASE64加密/解密

          Base64 编码是我们程序开发中经常使用到的编码方法,它用 64 个可打印字符来表示二进制数据。这 64 个字符是:小写字母 a-z、大写字母 A-Z、数字 0-9、符号"+"、"/"(再加上作为垫字的"=",实际上是 65 个字符),其他所有符号都转换成这个字符集中的字符。Base64 编码通常用作存储、传输一些二进制数据编码方法,所以说它本质上是一种将二进制数据转成文本数据的方案。

          通常用作对二进制数据进行加密,示例:

    
     
    1. import sun.misc.BASE64Decoder;
    2. import sun.misc.BASE64Encoder;
    3. public class Base64Util {
    4. /***
    5. * BASE64解密
    6. * @param key
    7. * @return
    8. * @throws Exception
    9. */
    10. public static byte[] decryBASE64(String key) throws Exception{
    11. return ( new BASE64Decoder()).decodeBuffer(key);
    12. }
    13. /***
    14. * BASE64加密
    15. * @param key
    16. * @return
    17. * @throws Exception
    18. */
    19. public static String encryptBASE64(byte[] key) throws Exception{
    20. return ( new BASE64Encoder()).encode(key);
    21. }
    22. }

     

    2.MD5(Message Digest Algorithm)加密/解密

           MD5 是将任意长度的数据字符串转化成短小的固定长度的值的单向操作,任意两个字符串不应有相同的散列值。因此 MD5 经常用于校验字符串或者文件,因为如果文件的 MD5 不一样,说明文件内容也是不一样的,如果发现下载的文件和给定的 MD5 值不一样,就要慎重使用。

           MD5 主要用做数据一致性验证、数字签名和安全访问认证,而不是用作加密。比如说用户在某个网站注册账户时,输入的密码一般经过 MD5 编码,更安全的做法还会加一层盐(salt),这样密码就具有不可逆性。然后把编码后的密码存入数据库,下次登录的时候把密码 MD5 编码,然后和数据库中的作对比,这样就提升了用户账户的安全性。

        是一种单向加密算法,只能加密不能解密,示例:

    
     
    1. import java.security.MessageDigest;
    2. public class MD5Util {
    3. public static final String KEY_MD5 = "MD5";
    4. /***
    5. * MD5加密(生成唯一的MD5值)
    6. * @param data
    7. * @return
    8. * @throws Exception
    9. */
    10. public static byte[] encryMD5( byte[] data) throws Exception {
    11. MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
    12. md5.update(data);
    13. return md5.digest();
    14. }
    15. }

     

    3.DES(Data Encryption Standard)对称加密/解密

           DES 是一种对称加密算法,所谓对称加密算法就是:加密和解密使用相同密钥的算法。DES 加密算法出自 IBM 的研究,后来被美国政府正式采用,之后开始广泛流传。但近些年使用越来越少,因为 DES 使用 56 位密钥,以现代的计算能力,24 小时内即可被破解。

          顺便说一下 3DES(Triple DES),它是 DES 向 AES 过渡的加密算法,使用 3 条 56 位的密钥对数据进行三次加密。是 DES 的一个更安全的变形。它以 DES 为基本模块,通过组合分组方法设计出分组加密算法。比起最初的 DES,3DES 更为安全。

           使用 Java 实现 DES 加密解密,注意密码长度要是 8 的倍数。加密和解密的 Cipher 构造参数一定要相同,不然会报错。

           数据加密标准算法,和BASE64最明显的区别就是有一个工作密钥,该密钥既用于加密、也用于解密,并且要求密钥是一个长度至少大于8位的字符串,示例:

    
     
    1. import java.security.Key;
    2. import java.security.SecureRandom;
    3. import javax.crypto.Cipher;
    4. import javax.crypto.KeyGenerator;
    5. import sun.misc.BASE64Decoder;
    6. import sun.misc.BASE64Encoder;
    7. public class DesUtil {
    8. private static Key key;
    9. private static String KEY_STR= "myKey";
    10. private static String CHARSETNAME= "UTF-8";
    11. private static String ALGORITHM= "DES";
    12. static {
    13. try {
    14. //生成DES算法对象
    15. KeyGenerator generator=KeyGenerator.getInstance(ALGORITHM);
    16. //运用SHA1安全策略
    17. SecureRandom secureRandom=SecureRandom.getInstance( "SHA1PRNG");
    18. //设置上密钥种子
    19. secureRandom.setSeed(KEY_STR.getBytes());
    20. //初始化基于SHA1的算法对象
    21. generator.init(secureRandom);
    22. //生成密钥对象
    23. key=generator.generateKey();
    24. generator= null;
    25. } catch (Exception e) {
    26. throw new RuntimeException(e);
    27. }
    28. }
    29. /***
    30. * 获取加密的信息
    31. * @param str
    32. * @return
    33. */
    34. public static String getEncryptString(String str) {
    35. //基于BASE64编码,接收byte[]并转换成String
    36. BASE64Encoder encoder = new BASE64Encoder();
    37. try {
    38. //按utf8编码
    39. byte[] bytes = str.getBytes(CHARSETNAME);
    40. //获取加密对象
    41. Cipher cipher = Cipher.getInstance(ALGORITHM);
    42. //初始化密码信息
    43. cipher.init(Cipher.ENCRYPT_MODE, key);
    44. //加密
    45. byte[] doFinal = cipher.doFinal(bytes);
    46. //byte[]to encode好的String 并返回
    47. return encoder.encode(doFinal);
    48. } catch (Exception e) {
    49. throw new RuntimeException(e);
    50. }
    51. }
    52. /***
    53. * 获取解密之后的信息
    54. * @param str
    55. * @return
    56. */
    57. public static String getDecryptString(String str) {
    58. BASE64Decoder decoder = new BASE64Decoder();
    59. try {
    60. //将字符串decode成byte[]
    61. byte[] bytes = decoder.decodeBuffer(str);
    62. //获取解密对象
    63. Cipher cipher = Cipher.getInstance(ALGORITHM);
    64. //初始化解密信息
    65. cipher.init(Cipher.DECRYPT_MODE, key);
    66. //解密
    67. byte[] doFial = cipher.doFinal(bytes);
    68. return new String(doFial, CHARSETNAME);
    69. } catch (Exception e) {
    70. throw new RuntimeException(e);
    71. }
    72. }
    73. }

     

    4.AES(Advanced Encryption Standard) 加密/解密

           高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称 Rijndael 加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的 DES,已经被多方分析且广为全世界所使用。简单说就是 DES 的增强版,比 DES 的加密强度更高。

           AES 与 DES 一样,一共有四种加密模式:电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)。关于加密模式的介绍,推荐这篇文章:高级加密标准AES的工作模式(ECB、CBC、CFB、OFB)

    示例代码:

    
     
    1. import javax.crypto.Cipher;
    2. import javax.crypto.spec.IvParameterSpec;
    3. import javax.crypto.spec.SecretKeySpec;
    4. public class AESUtil {
    5. public static final String algorithm = "AES";
    6. // AES/CBC/NOPaddin
    7. // AES 默认模式
    8. // 使用CBC模式, 在初始化Cipher对象时, 需要增加参数, 初始化向量IV : IvParameterSpec iv = new
    9. // IvParameterSpec(key.getBytes());
    10. // NOPadding: 使用NOPadding模式时, 原文长度必须是8byte的整数倍
    11. public static final String transformation = "AES/CBC/NOPadding";
    12. public static final String key = "1234567812345678";
    13. /***
    14. * 加密
    15. * @param original 需要加密的参数(注意必须是16位)
    16. * @return
    17. * @throws Exception
    18. */
    19. public static String encryptByAES(String original) throws Exception {
    20. // 获取Cipher
    21. Cipher cipher = Cipher.getInstance(transformation);
    22. // 生成密钥
    23. SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);
    24. // 指定模式(加密)和密钥
    25. // 创建初始化向量
    26. IvParameterSpec iv = new IvParameterSpec(key.getBytes());
    27. cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
    28. // cipher.init(Cipher.ENCRYPT_MODE, keySpec);
    29. // 加密
    30. byte[] bytes = cipher.doFinal(original.getBytes());
    31. return Base64Util.encryptBASE64(bytes);
    32. }
    33. /**
    34. * 解密
    35. * @param encrypted 需要解密的参数
    36. * @return
    37. * @throws Exception
    38. */
    39. public static String decryptByAES(String encrypted) throws Exception {
    40. // 获取Cipher
    41. Cipher cipher = Cipher.getInstance(transformation);
    42. // 生成密钥
    43. SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);
    44. // 指定模式(解密)和密钥
    45. // 创建初始化向量
    46. IvParameterSpec iv = new IvParameterSpec(key.getBytes());
    47. cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
    48. // cipher.init(Cipher.DECRYPT_MODE, keySpec);
    49. // 解密
    50. byte[] bytes = cipher.doFinal(Base64Util.decryBASE64(encrypted));
    51. return new String(bytes);
    52. }
    53. }

     

    5.HMAC(Hash Message Authentication Code,散列消息鉴别码)

           使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证,示例:

    
     
    1. import javax.crypto.KeyGenerator;
    2. import javax.crypto.Mac;
    3. import javax.crypto.SecretKey;
    4. import javax.crypto.spec.SecretKeySpec;
    5. public class HMACUtil {
    6. public static final String KEY_MAC = "HmacMD5";
    7. /***
    8. * 初始化HMAC密钥
    9. * @return
    10. * @throws Exception
    11. */
    12. public static String initMacKey() throws Exception{
    13. KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);
    14. SecretKey secreKey = keyGenerator.generateKey();
    15. return Base64Util.encryptBASE64(secreKey.getEncoded());
    16. }
    17. /**
    18. * HMAC加密
    19. * @param data
    20. * @param key
    21. * @return
    22. * @throws Exception
    23. */
    24. public static byte[] encryHMAC( byte[] data, String key) throws Exception{
    25. SecretKey secreKey = new SecretKeySpec(Base64Util.decryBASE64(key), KEY_MAC);
    26. Mac mac = Mac.getInstance(secreKey.getAlgorithm());
    27. mac.init(secreKey);
    28. return mac.doFinal();
    29. }
    30. }

     

    6.恺撒加密

    • 在密码学中,恺撒密码是一种最简单并且最广为人知的加密技术。

    • 它是一种替换加密的技术,明文中的所欲字母都在字母表上向后(或向前)按照一个固定的数目进行偏移后被替换成密文。

    • 例如:当偏移量是3的时候,所有的字母A将被替换成D,B变成E,以此类推。

    • 这个加密方法是以恺撒的名字命名的,当年恺撒曾用此方法与其将军们进行联系。

    • 恺撒密码通常被座位其他更复杂的加密方法中的一个步骤。

    示例代码:

    
     
    1. public class KaisaUtil {
    2. /***
    3. * 使用凯撒加密方式加密数据
    4. * @param orignal 原文
    5. * @param key 密钥
    6. * @return 加密后的字符
    7. */
    8. private static String encryptKaisa(String orignal, int key) {
    9. //将字符串转换为数组
    10. char[] chars = orignal.toCharArray();
    11. StringBuffer buffer = new StringBuffer();
    12. //遍历数组
    13. for( char aChar : chars) {
    14. //获取字符的ASCII编码
    15. int asciiCode = aChar;
    16. //偏移数据
    17. asciiCode += key;
    18. //将偏移后的数据转为字符
    19. char result = ( char)asciiCode;
    20. //拼接数据
    21. buffer.append(result);
    22. }
    23. return buffer.toString();
    24. }
    25. /**
    26. * 使用凯撒加密方式解密数据
    27. *
    28. * @param encryptedData :密文
    29. * @param key :密钥
    30. * @return : 源数据
    31. */
    32. private static String decryptKaiser(String encryptedData, int key) {
    33. // 将字符串转为字符数组
    34. char[] chars = encryptedData.toCharArray();
    35. StringBuilder sb = new StringBuilder();
    36. // 遍历数组
    37. for ( char aChar : chars) {
    38. // 获取字符的ASCII编码
    39. int asciiCode = aChar;
    40. // 偏移数据
    41. asciiCode -= key;
    42. // 将偏移后的数据转为字符
    43. char result = ( char) asciiCode;
    44. // 拼接数据
    45. sb.append(result);
    46. }
    47. return sb.toString();
    48. }
    49. public static void main(String[] args) {
    50. String str = "open fire";
    51. String encode = encryptKaisa(str, 3);
    52. System.out.println( "加密后:"+encode);
    53. String decode = decryptKaiser(encode, 3);
    54. System.out.println( "解密后:"+decode);
    55. }
    56. }

     

    7.SHA(Secure Hash Algorithm,安全散列算法)

            SHA全名叫做安全散列算法,是FIPS所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的机率很高。

            数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域,示例:

    
     
    1. import java.security.MessageDigest;
    2. public class SHAUtil {
    3. public static final String KEY_SHA = "SHA";
    4. /***
    5. * SHA加密(比MD5更安全)
    6. * @param data
    7. * @return
    8. * @throws Exception
    9. */
    10. public static byte[] encryptSHA( byte[] data) throws Exception{
    11. MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
    12. sha.update(data);
    13. return sha.digest();
    14. }
    15. public static String SHAEncrypt(final String content) {
    16. try {
    17. MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
    18. byte[] sha_byte = sha.digest(content.getBytes());
    19. StringBuffer hexValue = new StringBuffer();
    20. for ( byte b : sha_byte) {
    21. //将其中的每个字节转成十六进制字符串:byte类型的数据最高位是符号位,通过和0xff进行与操作,转换为int类型的正整数。
    22. String toHexString = Integer.toHexString(b & 0xff);
    23. hexValue.append(toHexString.length() == 1 ? "0" + toHexString : toHexString);
    24. }
    25. return hexValue.toString();
    26. } catch (Exception e) {
    27. e.printStackTrace();
    28. }
    29. return "";
    30. }
    31. }

     

    8.RSA 加密/解密

           RSA算法是一种非对称加密算法,所谓非对称就是该算法需要一对密钥,若使用其中一个加密,则需要用另一个才能解密。目前它是最有影响力和最常用的公钥加密算法,能够抵抗已知的绝大多数密码攻击。从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。

           该算法基于一个的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。由于进行的都是大数计算,RSA 最快的情况也比 DES 慢上好几倍,比对应同样安全级别的对称密码算法要慢 1000 倍左右。所以 RSA 一般只用于少量数据加密,比如说交换对称加密的密钥。

    使用 RSA 加密主要有这么几步:生成密钥对、公开公钥、公钥加密私钥解密、私钥加密公钥解密。

    示例代码:

    
     
    1. import com.sun.org.apache.xml.internal.security.utils.Base64;
    2. import javax.crypto.Cipher;
    3. import org.apache.commons.io.FileUtils;
    4. import java.io.ByteArrayOutputStream;
    5. import java.io.File;
    6. import java.nio.charset.Charset;
    7. import java.security.*;
    8. import java.security.spec.PKCS8EncodedKeySpec;
    9. import java.security.spec.X509EncodedKeySpec;
    10. public class RsaUtil {
    11. /**
    12. * 生成密钥对并保存在本地文件中
    13. *
    14. * @param algorithm : 算法
    15. * @param pubPath : 公钥保存路径
    16. * @param priPath : 私钥保存路径
    17. * @throws Exception
    18. */
    19. private static void generateKeyToFile(String algorithm, String pubPath, String priPath) throws Exception {
    20. // 获取密钥对生成器
    21. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
    22. // 获取密钥对
    23. KeyPair keyPair = keyPairGenerator.generateKeyPair();
    24. // 获取公钥
    25. PublicKey publicKey = keyPair.getPublic();
    26. // 获取私钥
    27. PrivateKey privateKey = keyPair.getPrivate();
    28. // 获取byte数组
    29. byte[] publicKeyEncoded = publicKey.getEncoded();
    30. byte[] privateKeyEncoded = privateKey.getEncoded();
    31. // 进行Base64编码
    32. String publicKeyString = Base64.encode(publicKeyEncoded);
    33. String privateKeyString = Base64.encode(privateKeyEncoded);
    34. // 保存文件
    35. FileUtils.writeStringToFile( new File(pubPath), publicKeyString, Charset.forName( "UTF-8"));
    36. FileUtils.writeStringToFile( new File(priPath), privateKeyString, Charset.forName( "UTF-8"));
    37. }
    38. /**
    39. * 从文件中加载公钥
    40. *
    41. * @param algorithm : 算法
    42. * @param filePath : 文件路径
    43. * @return : 公钥
    44. * @throws Exception
    45. */
    46. private static PublicKey loadPublicKeyFromFile(String algorithm, String filePath) throws Exception {
    47. // 将文件内容转为字符串
    48. String keyString = FileUtils.readFileToString( new File(filePath), Charset.forName( "UTF-8"));
    49. return loadPublicKeyFromString(algorithm, keyString);
    50. }
    51. /**
    52. * 从字符串中加载公钥
    53. *
    54. * @param algorithm : 算法
    55. * @param keyString : 公钥字符串
    56. * @return : 公钥
    57. * @throws Exception
    58. */
    59. private static PublicKey loadPublicKeyFromString(String algorithm, String keyString) throws Exception {
    60. // 进行Base64解码
    61. byte[] decode = Base64.decode(keyString);
    62. // 获取密钥工厂
    63. KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
    64. // 构建密钥规范
    65. X509EncodedKeySpec keyspec = new X509EncodedKeySpec(decode);
    66. // 获取公钥
    67. return keyFactory.generatePublic(keyspec);
    68. }
    69. /**
    70. * 从文件中加载私钥
    71. *
    72. * @param algorithm : 算法
    73. * @param filePath : 文件路径
    74. * @return : 私钥
    75. * @throws Exception
    76. */
    77. private static PrivateKey loadPrivateKeyFromFile(String algorithm, String filePath) throws Exception {
    78. // 将文件内容转为字符串
    79. String keyString = FileUtils.readFileToString( new File(filePath), Charset.forName( "UTF-8"));
    80. return loadPrivateKeyFromString(algorithm, keyString);
    81. }
    82. /**
    83. * 从字符串中加载私钥
    84. *
    85. * @param algorithm : 算法
    86. * @param keyString : 私钥字符串
    87. * @return : 私钥
    88. * @throws Exception
    89. */
    90. private static PrivateKey loadPrivateKeyFromString(String algorithm, String keyString) throws Exception {
    91. // 进行Base64解码
    92. byte[] decode = Base64.decode(keyString);
    93. // 获取密钥工厂
    94. KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
    95. // 构建密钥规范
    96. PKCS8EncodedKeySpec keyspec = new PKCS8EncodedKeySpec(decode);
    97. // 生成私钥
    98. return keyFactory.generatePrivate(keyspec);
    99. }
    100. /**
    101. * 使用密钥加密数据
    102. *
    103. * @param algorithm : 算法
    104. * @param input : 原文
    105. * @param key : 密钥
    106. * @param maxEncryptSize : 最大加密长度(需要根据实际情况进行调整)
    107. * @return : 密文
    108. * @throws Exception
    109. */
    110. private static String encrypt(String algorithm, String input, Key key, int maxEncryptSize) throws Exception {
    111. // 获取Cipher对象
    112. Cipher cipher = Cipher.getInstance(algorithm);
    113. // 初始化模式(加密)和密钥
    114. cipher.init(Cipher.ENCRYPT_MODE, key);
    115. // 将原文转为byte数组
    116. byte[] data = input.getBytes();
    117. // 总数据长度
    118. int total = data.length;
    119. // 输出流
    120. ByteArrayOutputStream baos = new ByteArrayOutputStream();
    121. decodeByte(maxEncryptSize, cipher, data, total, baos);
    122. // 对密文进行Base64编码
    123. return Base64.encode(baos.toByteArray());
    124. }
    125. /**
    126. * 解密数据
    127. *
    128. * @param algorithm : 算法
    129. * @param encrypted : 密文
    130. * @param key : 密钥
    131. * @param maxDecryptSize : 最大解密长度(需要根据实际情况进行调整)
    132. * @return : 原文
    133. * @throws Exception
    134. */
    135. private static String decrypt(String algorithm, String encrypted, Key key, int maxDecryptSize) throws Exception {
    136. // 获取Cipher对象
    137. Cipher cipher = Cipher.getInstance(algorithm);
    138. // 初始化模式(解密)和密钥
    139. cipher.init(Cipher.DECRYPT_MODE, key);
    140. // 由于密文进行了Base64编码, 在这里需要进行解码
    141. byte[] data = Base64.decode(encrypted);
    142. // 总数据长度
    143. int total = data.length;
    144. // 输出流
    145. ByteArrayOutputStream baos = new ByteArrayOutputStream();
    146. decodeByte(maxDecryptSize, cipher, data, total, baos);
    147. // 输出原文
    148. return baos.toString();
    149. }
    150. /**
    151. * 分段处理数据
    152. *
    153. * @param maxSize : 最大处理能力
    154. * @param cipher : Cipher对象
    155. * @param data : 要处理的byte数组
    156. * @param total : 总数据长度
    157. * @param baos : 输出流
    158. * @throws Exception
    159. */
    160. private static void decodeByte(int maxSize, Cipher cipher, byte[] data, int total, ByteArrayOutputStream baos) throws Exception {
    161. // 偏移量
    162. int offset = 0;
    163. // 缓冲区
    164. byte[] buffer;
    165. // 如果数据没有处理完, 就一直继续
    166. while (total - offset > 0) {
    167. // 如果剩余的数据 >= 最大处理能力, 就按照最大处理能力来加密数据
    168. if (total - offset >= maxSize) {
    169. // 加密数据
    170. buffer = cipher.doFinal(data, offset, maxSize);
    171. // 偏移量向右侧偏移最大数据能力个
    172. offset += maxSize;
    173. } else {
    174. // 如果剩余的数据 < 最大处理能力, 就按照剩余的个数来加密数据
    175. buffer = cipher.doFinal(data, offset, total - offset);
    176. // 偏移量设置为总数据长度, 这样可以跳出循环
    177. offset = total;
    178. }
    179. // 向输出流写入数据
    180. baos.write(buffer);
    181. }
    182. }
    183. }

      加密算法的安全级别(Security Level of Cryptographic Algorithms):

    安全级别 
    (Security Level)
    工作因素 
    (Work Factor)
    算法 
    (Algorithms)
    薄弱(Weak)O(240)DESMD5
    传统(Legacy)O(264)RC4SHA-1
    基准(Baseline)O(280)3DES
    标准(Standard)O(2128)AES-128SHA-256
    较高(High)O(2192)AES-192SHA-384
    超高(Ultra)O(2256)AES-256SHA-512

     

    9.PBE 加密/解密

         PBE是一种基于口令的加密算法,使用口令代替其他对称加密算法中的密钥,其特点在于口令由用户自己掌管,不借助任何物理媒体;采用随机数(这里我们叫做盐)杂凑多重加密等方法保证数据的安全性。

         PBE算法是对称加密算法的综合算法,常见算法PBEWithMD5AndDES,使用MD5和DES算法构建了PBE算法。将盐附加在口令上,通过消息摘要算法经过迭代获得构建密钥的基本材料,构建密钥后使用对称加密算法进行加密解密。

    算法/密钥长度/默认密钥长度:

    1.PBEWithMD5AndDES/56/56
    2.PBEWithMD5AndTripleDES/112,168/168
    3.PBEWithSHA1AndDESede/112,168/168
    4.PBEWithSHA1AndRC2_40/40 to 1024/128

    工作模式:CBC
    填充方式:PKCS5Padding

    示例代码:

    
     
    1. import java.security.Key;
    2. import java.security.SecureRandom;
    3. import javax.crypto.Cipher;
    4. import javax.crypto.SecretKeyFactory;
    5. import javax.crypto.spec.PBEKeySpec;
    6. import javax.crypto.spec.PBEParameterSpec;
    7. public class PBEUtil {
    8. public static final String ALGORITHM = "PBEWITHMD5andDES";
    9. public static final int ITERATION_COUNT = 100;
    10. public static byte[] initSalt() throws Exception{
    11. //实例化安全随机数
    12. SecureRandom random = new SecureRandom();
    13. return random.generateSeed( 8);
    14. }
    15. /***
    16. * 转换密钥
    17. * @param password 密码
    18. * @return 密钥
    19. * @throws Exception
    20. */
    21. private static Key toKey(String password) throws Exception{
    22. //密钥材料
    23. PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
    24. //实例化
    25. SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
    26. //生成密钥
    27. return factory.generateSecret(keySpec);
    28. }
    29. /***
    30. * 加密
    31. * @param data 待加密数据
    32. * @param password 密钥
    33. * @param salt
    34. * @return
    35. * @throws Exception
    36. */
    37. public static byte[] encrypt( byte[] data, String password, byte[] salt) throws Exception{
    38. //转换密钥
    39. Key key = toKey(password);
    40. //实例化PBE参数材料
    41. PBEParameterSpec spec = new PBEParameterSpec(salt, ITERATION_COUNT);
    42. //实例化
    43. Cipher cipher = Cipher.getInstance(ALGORITHM);
    44. //初始化
    45. cipher.init(Cipher.ENCRYPT_MODE, key, spec);
    46. return cipher.doFinal(data);
    47. }
    48. /***
    49. * 解密
    50. * @param data 待解密数据
    51. * @param password 密钥
    52. * @param salt
    53. * @return
    54. * @throws Exception
    55. */
    56. public static byte[] decrypt( byte[] data, String password, byte[] salt) throws Exception{
    57. //转换密钥
    58. Key key = toKey(password);
    59. //实例化PBE参数材料
    60. PBEParameterSpec spec = new PBEParameterSpec(salt, ITERATION_COUNT);
    61. //实例化
    62. Cipher cipher = Cipher.getInstance(ALGORITHM);
    63. //初始化
    64. cipher.init(Cipher.DECRYPT_MODE, key, spec);
    65. //执行操作
    66. return cipher.doFinal(data);
    67. }
    68. private static String showByteArray(byte[] data) {
    69. if( null == data) {
    70. return null;
    71. }
    72. StringBuilder sb = new StringBuilder();
    73. for( byte b : data) {
    74. sb.append(b).append( ",");
    75. }
    76. sb.deleteCharAt(sb.length()- 1);
    77. sb.append( "");
    78. return sb.toString();
    79. }
    80. public static void main(String[] args) throws Exception{
    81. byte[] salt = initSalt();
    82. System.out.println( "salt:"+showByteArray(salt));
    83. String password = "1111";
    84. System.out.println( "口令:"+password);
    85. String data = "PBE数据";
    86. System.out.println( "加密前数据:String:"+data);
    87. System.out.println( "加密前数据:byte[]:"+showByteArray(data.getBytes()));
    88. byte[] encryptData = encrypt(data.getBytes(), password, salt);
    89. System.out.println( "加密后数据:byte[]:"+showByteArray(encryptData));
    90. byte[] decryptData = decrypt(encryptData, password, salt);
    91. System.out.println( "解密后数据: byte[]:"+showByteArray(decryptData));
    92. System.out.println( "解密后数据: string:"+ new String(decryptData));
    93. }
    94. }

     

    本篇文章参考了以下两位的文章,感谢

    https://www.jianshu.com/p/26adec49cb34

    https://www.jianshu.com/p/213d69ac27b3

            <div class="person-messagebox">
                <div class="left-message"><a href="https://blog.csdn.net/theUncle">
                    <img src="https://profile.csdnimg.cn/B/5/1/3_theuncle" class="avatar_pic" username="theUncle">
                </a></div>
                <div class="middle-message">
                                        <div class="title"><span class="tit "><a href="https://blog.csdn.net/theUncle" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;,&quot;ab&quot;:&quot;new&quot;}" target="_blank">theUncle</a></span>
                        <!-- 等级,level -->
                                                <img class="identity-icon" src="https://csdnimg.cn/identity/blog2.png">                                            </div>
                    <div class="text"><span>原创文章 5</span><span>获赞 12</span><span>访问量 2万+</span></div>
                </div>
                                <div class="right-message">
                                            <a class="btn btn-sm  bt-button personal-watch" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;,&quot;ab&quot;:&quot;new&quot;}">关注</a>
                                                                <a href="https://im.csdn.net/im/main.html?userName=theUncle" target="_blank" class="btn btn-sm bt-button personal-letter">私信
                        </a>
                                    </div>
                            </div>
                        
        </div>
    

    原文链接:https://blog.csdn.net/theUncle/article/details/100156976

    展开全文
  • 主要介绍了如何通过Java实现加密解密Word文档,对一些重要文档,常需要对文件进行加密,查看文件时,需要正确输入密码才能打开文件。下面介绍了一种比较简单的方法给Word文件加密以及如何给已加密的Word文件解除...
  • java 文件 加密 解密

    2013-02-18 09:36:20
    java 文件 加密 解密 内涵源码(eclipse项目),运行jar包。
  • Java加密与解密的艺术》作者相关文章 Java加密技术(一)——BASE64单向加密算法MD5&SHA&MAC Java加密技术(二)——对称加密DES&AES Java加密技术(三)——PBE算法 Java加密技术(四)——非对称...
  • Java文件加密解密

    2010-07-09 13:21:05
    Java实现的一文件加密解密功能,可自己设定密钥对指定文件加密,解密
  • java 文件加密解密操作 java 文件加密解密操作
  • Java 文件加密解密

    2009-06-05 00:22:41
    Java 文件加密解密器 可对所有文件进行加密和解密,第一次运行加密,第二次运行解密。
  • java实现文件加密解密

    2016-10-25 10:19:48
    利用java实现将资源文件(包括图片、动画等类型)进行简单的加密解密
  • Java实现DES加密解密

    万次阅读 多人点赞 2018-11-09 16:27:01
    DES(Data Encryption Standard)是一种对称加密算法,所谓对称加密就是加密解密都是使用同一个密钥。 加密原理: DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。这是一个迭代的...
  • java加密与解密

    2010-12-19 20:24:00
    谁有《java加密与解密的艺术》这本书啊?
  • java文件加密解密

    2010-08-15 23:25:04
    java做的一个简单的文件加密解密器,可以对单个的文件进行加密,加密后还可以解密,图形界面的
  • java des加密与解密

    千次阅读 2009-05-04 17:03:00
    package des;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream; import javax.crypto.Cipher;import javax.crypto.CipherInputStream;import javax.cry
  • Java AES加密解密

    千次阅读 2020-06-04 09:32:19
    本文向您展示了一些Java AES加密解密示例: AES字符串加密–(加密解密字符串)。 AES基于密码的加密–(密钥将从给定的密码派生)。 AES文件加密。 (基于密码)。 在本文中,我们重点介绍...
  • DES java 文件加密 解密

    2013-06-06 01:11:13
    用des算法对文件进行加解密 java语言实现
  • Java RSA 加密解密

    2017-11-18 16:31:49
    Java RSA 加密 解密 完整代码 适合 字符 及文件解密
  • 本文在oracle jdk 1.8, delphi xe3下面测试...java加密与解密算法代码 package com.shit; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOut
  • Java实现文件加密与解密

    千次阅读 2019-03-18 15:02:41
    最近在做一个项目,需要将资源文件(包括图片、动画等类型)进行简单的加密后再上传至云上的服务器,而在应用程序中对该资源使用前先将读取到的文件数据进行解密以得到真正的文件信息。此策略的原因好处是将准备好...
  • java SRA加密与解密

    千次阅读 2012-11-21 11:30:46
    import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputS
  • 包括java自定义加密解密实例,异或加密解密实例,AES加密解密,DES加密解密文件加密建议使用DES方式 技术学习交流:635278789
  • java加密与解密(一)

    万次阅读 2019-06-28 00:45:31
    纵观密码学的发展史,它共经历了三个阶段,分别是手工加密阶段、机械加密阶段和计算机加密阶段。手工加密阶段最为漫长,期间孕育了古典密码,这为后期密码学的发展奠定了基础。机械工业革命发展的同时促进着各种...
  • java encrpty and decrpty files 加密与解密文件
  • des加密算法(js+java)加密解密结果相同 包含三个文件 : des.js des.html ,用于实现前端脚本的加密... des.java 用于后台的加密解密操作; 项目中正好用到,已经过验证,两个加密解密结果相同,分享给大家!

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 55,604
精华内容 22,241
关键字:

java文件的加密与解密

java 订阅