1 | import java.net.*; |
2 | import java.io.*; |
3 | import javax.swing.*; |
4 | import java.util.regex.*; |
5 | import java.util.*; |
6 | |
7 | import java.security.*; |
8 | import java.security.spec.*; |
9 | import javax.crypto.*; |
10 | import javax.crypto.spec.*; |
11 | |
12 | public class main { |
13 | public static void main(String[] args) throws Exception { |
14 | byte[] data = "hello".getBytes("UTF-8"); |
15 | printHex(data); |
16 | |
17 | Random ranGen = new SecureRandom(); |
18 | byte[] salt = new byte[8]; // 8 grains of salt |
19 | ranGen.nextBytes(salt); |
20 | |
21 | String pw = "pw"; |
22 | byte[] enc = encrypt(data, pw.toCharArray(), salt); |
23 | printHex(enc); |
24 | System.out.println("enc length: " + enc.length); |
25 | |
26 | byte[] dec = decrypt(enc, pw.toCharArray(), salt); |
27 | System.out.println("decrypted: " + new String(dec, "UTF-8")); |
28 | } |
29 | |
30 | static void printHex(byte[] data) { |
31 | System.out.println(bytesToHex(data)); |
32 | } |
33 | |
34 | static String bytesToHex(byte[] bytes) { |
35 | return bytesToHex(bytes, 0, bytes.length); |
36 | } |
37 | |
38 | static String bytesToHex(byte[] bytes, int ofs, int len) { |
39 | StringBuilder stringBuilder = new StringBuilder(len*2); |
40 | for (int i = 0; i < len; i++) { |
41 | String s = "0" + Integer.toHexString(bytes[ofs+i]); |
42 | stringBuilder.append(s.substring(s.length()-2, s.length())); |
43 | } |
44 | return stringBuilder.toString(); |
45 | } |
46 | |
47 | static SecretKey makeKey(char[] password, byte[] salt) throws Exception { |
48 | /* Derive the key, given password and salt. */ |
49 | SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); |
50 | |
51 | // only with unlimited strength: |
52 | //KeySpec spec = new PBEKeySpec(password, salt, 65536, 256); |
53 | |
54 | // Let's try this: |
55 | KeySpec spec = new PBEKeySpec(password, salt, 65536, 128); |
56 | |
57 | SecretKey tmp = factory.generateSecret(spec); |
58 | SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); |
59 | return secret; |
60 | } |
61 | |
62 | public static byte[] encrypt(byte[] data, char[] password, byte[] salt) { |
63 | try { |
64 | SecretKey secret = makeKey(password, salt); |
65 | |
66 | /* Encrypt the message. */ |
67 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); |
68 | cipher.init(Cipher.ENCRYPT_MODE, secret); |
69 | AlgorithmParameters params = cipher.getParameters(); |
70 | byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV(); |
71 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
72 | baos.write(cipher.update(data)); |
73 | baos.write(cipher.doFinal()); |
74 | byte[] ciphertext = baos.toByteArray(); |
75 | return ciphertext; |
76 | } catch (Exception e) { |
77 | throw new RuntimeException(e); |
78 | } |
79 | } |
80 | |
81 | static byte[] decrypt(byte[] ciphertext, char[] password, byte[] salt) { |
82 | try { |
83 | SecretKey secret = makeKey(password, salt); |
84 | |
85 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); |
86 | cipher.init(Cipher.ENCRYPT_MODE, secret); |
87 | AlgorithmParameters params = cipher.getParameters(); |
88 | byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV(); |
89 | |
90 | /* Decrypt the message, given derived key and initialization vector. */ |
91 | cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); |
92 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
93 | cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv)); |
94 | baos.write(cipher.update(ciphertext)); |
95 | baos.write(cipher.doFinal()); |
96 | return baos.toByteArray(); |
97 | } catch (Exception e) { |
98 | throw new RuntimeException(e); |
99 | } |
100 | } |
101 | } |
Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, teubizvjbppd, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1000344 |
Snippet name: | Encryption/decryption bug reproduction (for StackOverflow) |
Eternal ID of this version: | #1000344/1 |
Text MD5: | 2a809527de7d83a129f1ed6c5c62dc99 |
Author: | stefan |
Category: | |
Type: | Java source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2015-07-26 19:51:55 |
Source code size: | 3499 bytes / 101 lines |
Pitched / IR pitched: | No / Yes |
Views / Downloads: | 1121 / 159 |
Referenced in: | [show references] |