1 package org.matsim.core.utils.io;
3 import com.google.common.io.CharStreams;
5 import javax.crypto.Cipher;
6 import javax.crypto.CipherInputStream;
7 import javax.crypto.SecretKeyFactory;
8 import javax.crypto.spec.IvParameterSpec;
9 import javax.crypto.spec.PBEKeySpec;
10 import javax.crypto.spec.SecretKeySpec;
11 import java.io.FileInputStream;
12 import java.io.IOException;
13 import java.io.InputStream;
14 import java.io.InputStreamReader;
15 import java.nio.charset.StandardCharsets;
16 import java.security.GeneralSecurityException;
17 import java.security.Key;
18 import java.security.NoSuchAlgorithmException;
19 import java.security.spec.InvalidKeySpecException;
20 import java.util.Arrays;
45 private static Key
getKeyForFile(byte[] salt)
throws NoSuchAlgorithmException, InvalidKeySpecException {
47 SecretKeyFactory factory = SecretKeyFactory.getInstance(
"PBKDF2WithHmacSHA512");
49 String pw = System.getProperty(ENVIRONMENT_VARIABLE, System.getenv(ENVIRONMENT_VARIABLE));
52 throw new IllegalStateException(
"No password specified for encrypted file. Please set " + ENVIRONMENT_VARIABLE +
" environment variable.");
55 PBEKeySpec keySpec =
new PBEKeySpec(pw.toCharArray(), salt, 10000, 256 + 128);
57 return factory.generateSecret(keySpec);
68 public static InputStream
getDecryptedInput(InputStream is)
throws IOException, GeneralSecurityException {
70 byte[] header =
new byte[16];
72 if (is.read(header) != 16)
73 throw new IllegalStateException(
"Read too few bytes. Encrypted file is most likely corrupted.");
75 String h =
new String(header, 0, 8, StandardCharsets.US_ASCII);
77 if (!h.equals(
"Salted__"))
78 throw new IllegalStateException(
"File header must start with 'Salted__'.");
80 byte[] salt = Arrays.copyOfRange(header, 8, 16);
82 Cipher cipher = Cipher.getInstance(
"AES/CBC/PKCS5Padding");
86 SecretKeySpec secretKey =
new SecretKeySpec(tmp.getEncoded(), 0, 32,
"AES");
87 IvParameterSpec ivspec =
new IvParameterSpec(tmp.getEncoded(), 32, 16);
89 cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec);
91 return new CipherInputStream(is, cipher);
101 System.out.println(CharStreams.toString(
new InputStreamReader(is)));
static final String ENVIRONMENT_VARIABLE
static InputStream getDecryptedInput(InputStream is)
static void main(String[] args)
static Key getKeyForFile(byte[] salt)