PBE文件加密-Java应用实例
1 | import java.io.BufferedInputStream; |
2 | import java.io.BufferedOutputStream; |
3 | import java.io.File; |
4 | import java.io.FileInputStream; |
5 | import java.io.FileOutputStream; |
6 | import java.util.Random; |
7 |
8 | import javax.crypto.Cipher; |
9 | import javax.crypto.CipherInputStream; |
10 | import javax.crypto.CipherOutputStream; |
11 | import javax.crypto.SecretKey; |
12 | import javax.crypto.SecretKeyFactory; |
13 | import javax.crypto.spec.PBEKeySpec; |
14 | import javax.crypto.spec.PBEParameterSpec; |
15 |
16 | /** |
17 | * PBE 全称为Password-Based Encrypt(基于密码的加密)。 |
18 | */ |
19 | public class PBE_Encrypt { |
20 | private static String ALGORITHM1 = "PBE" ; |
21 | private static String ALGORITHM2 = "PBEWithMD5AndDES" ; |
22 | private static int ITERATIONCOUNT = 1000 ; // 迭代计数。 |
23 |
24 | /** |
25 | * 根据自定义密码生成密钥 |
26 | */ |
27 | public static SecretKey generateKey(String password) throws Exception { |
28 | PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray()); |
29 | SecretKeyFactory kf = SecretKeyFactory.getInstance(ALGORITHM1); |
30 | return kf.generateSecret(keySpec); |
31 | } |
32 |
33 | /** |
34 | * 加密文件 |
35 | * @param key密钥 |
36 | * @param sourceFile源文件 |
37 | * @param secretFile目标加密文件 |
38 | */ |
39 | public static void encryptFile(SecretKey key, File sourceFile, File secretFile) |
40 | throws Exception { |
41 | /** 产生一个随机盐 */ |
42 | byte [] salt = new byte [ 8 ]; |
43 | Random random = new Random(); |
44 | random.nextBytes(salt); |
45 |
46 | /** 为 PKCS #5 标准中所定义的基于密码的加密法构造一个参数集合 salt:复制该 salt 的内容来防止后续修改;1000:迭代计数 */ |
47 | PBEParameterSpec spec = new PBEParameterSpec(salt, ITERATIONCOUNT); |
48 | /** 得到Cipher对象来实现对源数据的PBEWithMD5AndDES加密 */ |
49 | Cipher cipher = Cipher.getInstance(ALGORITHM2); |
50 | cipher.init(Cipher.ENCRYPT_MODE, key, spec); |
51 | /** 构造文件缓冲输出流,并将随机盐写入密文头 */ |
52 | BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(secretFile)); |
53 | out.write(salt); |
54 | /** 构造源文件读取流 */ |
55 | BufferedInputStream in = new BufferedInputStream( new FileInputStream(sourceFile)); |
56 |
57 | /** 构造密文输出流,将源文件内容加密写入目标加密文件 */ |
58 | CipherOutputStream cos = new CipherOutputStream(out, cipher); |
59 | int b = - 1 ; |
60 | while ((b = in.read()) != - 1 ) { |
61 | cos.write(b); |
62 | } |
63 | cos.close(); |
64 | in.close(); |
65 | } |
66 |
67 | /** |
68 | * 解密文件 |
69 | * @param key 密钥 |
70 | * @param secretFile 加密文件 |
71 | * @param decryptFile 解密后文件 |
72 | */ |
73 | public static void decryptFile(SecretKey key, File secretFile, File decryptFile) |
74 | throws Exception { |
75 | /** 从加密文件中读取随机盐 */ |
76 | byte [] salt = new byte [ 8 ]; |
77 | BufferedInputStream bis = new BufferedInputStream( new FileInputStream(secretFile)); |
78 | bis.read(salt); |
79 |
80 | PBEParameterSpec spec = new PBEParameterSpec(salt, ITERATIONCOUNT); |
81 | /** 得到Cipher对象来实现对加密数据的PBEWithMD5AndDES解密 */ |
82 | Cipher cipher = Cipher.getInstance(ALGORITHM2); |
83 | cipher.init(Cipher.DECRYPT_MODE, key, spec); |
84 |
85 | BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(decryptFile)); |
86 | CipherInputStream in = new CipherInputStream(bis, cipher); |
87 |
88 | int b = - 1 ; |
89 | while ((b = in.read()) != - 1 ) { |
90 | out.write(b); |
91 | } |
92 | out.close(); |
93 | in.close(); |
94 | } |
95 |
96 | public static void main(String[] args) throws Exception { |
97 | SecretKey key = generateKey( "MySecretKey" ); // 用自定义的字符串生成一个可信密钥 |
98 | File sourceFile = new File( "D:\\test.jpg" ); // 源文件 |
99 | File secretFile = new File( "D:\\secret" ); // 加密目标文件 |
100 | File decryptFile = new File( "D:\\decrypt.jpg" ); // 解密目标文件 |
101 |
102 | /** 加密文件 */ |
103 | encryptFile(key, sourceFile, secretFile); |
104 |
105 | /** 解密文件 */ |
106 | decryptFile(key, secretFile, decryptFile); |
107 | } |
108 | } |