· 4 years ago · Jun 13, 2021, 03:00 AM
1package testaesencryption;
2
3import java.io.Serializable;
4import java.security.AlgorithmParameters;
5import java.security.NoSuchAlgorithmException;
6import java.security.SecureRandom;
7import java.security.spec.InvalidKeySpecException;
8import java.security.spec.KeySpec;
9import javax.crypto.Cipher;
10import javax.crypto.SecretKey;
11import javax.crypto.SecretKeyFactory;
12import javax.crypto.spec.IvParameterSpec;
13import javax.crypto.spec.PBEKeySpec;
14import javax.crypto.spec.SecretKeySpec;
15
16/**
17 * An object created for the purpose of storing the encrypted version of a
18 * Bittrex key and secret. The object is serializable so it can be written to
19 * and read from a binary file.
20 *
21 * The salt and iv are stored in the object. However, the password is not stored
22 * and should be either memorized, or it's input should come from a secure
23 * source.
24 *
25 * @author Brian M. Dean
26 */
27public class EncryptedKey implements Serializable {
28
29 private byte[] salt;
30 private byte[] ivdata;
31 private byte[] encrypted_key;
32 private byte[] encrypted_secret;
33
34 public EncryptedKey(String key, String secret, String password) {
35 try {
36 salt = new byte[8];
37 SecureRandom secureRandom = new SecureRandom();
38 secureRandom.nextBytes(salt);
39
40 SecretKeyFactory factory = SecretKeyFactory
41 .getInstance("PBKDF2WithHmacSHA1");
42 KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536,
43 256);
44 SecretKey secretKey = factory.generateSecret(keySpec);
45 SecretKey secretk = new SecretKeySpec(secretKey.getEncoded(), "AES");
46
47 //
48 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
49 cipher.init(Cipher.ENCRYPT_MODE, secretk);
50 AlgorithmParameters params = cipher.getParameters();
51 ivdata = params.getParameterSpec(IvParameterSpec.class).getIV();
52
53 // encrypt the key
54 byte[] keydata = cipher.update(key.getBytes());
55 byte[] saltdata = cipher.doFinal();
56 encrypted_key = new byte[keydata.length + saltdata.length];
57 for (int i = 0; i < keydata.length; i++) {
58 encrypted_key[i] = keydata[i];
59 }
60 for (int i = 0; i < saltdata.length; i++) {
61 encrypted_key[i + keydata.length] = saltdata[i];
62 }
63
64 // encrypt the secret
65 byte[] secretdata = cipher.update(secret.getBytes());
66 saltdata = cipher.doFinal();
67 encrypted_secret = new byte[secretdata.length + saltdata.length];
68 for (int i = 0; i < secretdata.length; i++) {
69 encrypted_secret[i] = secretdata[i];
70 }
71 for (int i = 0; i < saltdata.length; i++) {
72 encrypted_secret[i + secretdata.length] = saltdata[i];
73 }
74 } catch (Exception ex) {
75 System.err.println(ex.getMessage());
76 }
77
78 }
79
80 public EncryptedKey(byte[] sa, byte[] iv, byte[] key, byte[] secret) {
81 int siz = sa.length;
82 salt = new byte[siz];
83 for (int i = 0; i < siz; i++) {
84 salt[i] = sa[i];
85 }
86 siz = iv.length;
87 ivdata = new byte[siz];
88 for (int i = 0; i < siz; i++) {
89 ivdata[i] = iv[i];
90 }
91 siz = key.length;
92 encrypted_key = new byte[siz];
93 for (int i = 0; i < siz; i++) {
94 encrypted_key[i] = key[i];
95 }
96 siz = secret.length;
97 encrypted_secret = new byte[siz];
98 for (int i = 0; i < siz; i++) {
99 encrypted_secret[i] = secret[i];
100 }
101 }
102
103 public byte[] getSalt() {
104 return salt;
105 }
106
107 public byte[] getIV() {
108 return ivdata;
109 }
110
111 public byte[] getKeyData() {
112 return encrypted_key;
113
114 }
115
116 public byte[] getSecretData() {
117 return encrypted_secret;
118 }
119
120 public BittrexAPIKey decrypt(String password) {
121 try {
122 SecretKeyFactory factory = SecretKeyFactory
123 .getInstance("PBKDF2WithHmacSHA1");
124 KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536,
125 256);
126 SecretKey tmp = factory.generateSecret(keySpec);
127 SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
128
129 // file decryption
130 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
131 cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivdata));
132 byte[] testdata = cipher.update(encrypted_key);
133 byte[] testsalt = cipher.doFinal();
134 String keystr = new String(testdata);
135 testdata = cipher.update(encrypted_secret);
136 testsalt = cipher.doFinal();
137 String secretstr = new String(testdata);
138 return new BittrexAPIKey(keystr, secretstr);
139
140 } catch (Exception ex) {
141 System.err.println(ex.getMessage());
142 }
143 return null;
144 }
145
146}
147