Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
LicenseDecryptorUtil.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2023 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package com.basistech.df.cybertriage.autopsy.ctapi.util;
20
21import com.basistech.df.cybertriage.autopsy.ctapi.json.BoostLicenseResponse;
22import com.basistech.df.cybertriage.autopsy.ctapi.json.DecryptedLicenseResponse;
23import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseInfo;
24import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseResponse;
25import com.fasterxml.jackson.core.JsonProcessingException;
26import com.fasterxml.jackson.databind.ObjectMapper;
27import java.io.IOException;
28import java.nio.charset.StandardCharsets;
29import java.security.GeneralSecurityException;
30import java.security.InvalidKeyException;
31import java.security.KeyFactory;
32import java.security.NoSuchAlgorithmException;
33import java.security.PublicKey;
34import java.security.spec.InvalidKeySpecException;
35import java.security.spec.KeySpec;
36import java.security.spec.X509EncodedKeySpec;
37import java.text.MessageFormat;
38import java.util.Base64;
39import javax.crypto.BadPaddingException;
40import javax.crypto.Cipher;
41import javax.crypto.IllegalBlockSizeException;
42import javax.crypto.NoSuchPaddingException;
43import javax.crypto.SecretKey;
44import javax.crypto.spec.IvParameterSpec;
45import javax.crypto.spec.SecretKeySpec;
46import org.apache.commons.lang3.ObjectUtils;
47
52
54
56 return instance;
57 }
58
60
62 }
63
64 public LicenseInfo createLicenseInfo(LicenseResponse licenseResponse) throws JsonProcessingException, InvalidLicenseException {
65 if (licenseResponse == null) {
66 throw new InvalidLicenseException("License is null");
67 }
68
69 DecryptedLicenseResponse decrypted = parseLicenseJSON(licenseResponse.getBoostLicense());
70 return new LicenseInfo(licenseResponse, decrypted);
71 }
72
82 public DecryptedLicenseResponse parseLicenseJSON(BoostLicenseResponse licenseResponse) throws JsonProcessingException, InvalidLicenseException {
83 if (licenseResponse == null) {
84 throw new InvalidLicenseException("Boost license is null");
85 }
86
87 String decryptedJsonResponse;
88 try {
89 decryptedJsonResponse = decryptLicenseString(
90 licenseResponse.getEncryptedJson(),
91 licenseResponse.getIv(),
92 licenseResponse.getEncryptedKey(),
93 licenseResponse.getVersion()
94 );
95 } catch (IOException | GeneralSecurityException ex) {
96 throw new InvalidLicenseException("An exception occurred while parsing the license string", ex);
97 }
98
99 DecryptedLicenseResponse decryptedLicense = objectMapper.readValue(decryptedJsonResponse, DecryptedLicenseResponse.class);
100 if (!"AUTOPSY".equalsIgnoreCase(decryptedLicense.getProduct())) {
101 // license file is expected to contain product of "CYBERTRIAGE"
102 throw new InvalidLicenseException("Not a valid Autopsy license");
103 }
104
105 return decryptedLicense;
106 }
107
108 private String decryptLicenseString(String encryptedJson, String ivBase64, String encryptedKey, String version) throws IOException, GeneralSecurityException, InvalidLicenseException {
109 if (ObjectUtils.anyNull(encryptedJson, ivBase64, encryptedKey, version)) {
110 throw new InvalidLicenseException(MessageFormat.format(
111 "encryptedJson: {0}, iv: {1}, encryptedKey: {2}, version: {3} must all be non-null",
112 encryptedJson, ivBase64, encryptedKey, version));
113 }
114
115 if (!"1.0".equals(version)) {
116 throw new InvalidLicenseException("Unexpected file version: " + version);
117 }
118
119 byte[] encryptedKeyBytes = Base64.getDecoder().decode(encryptedKey);
120 byte[] keyBytes = decryptKey(encryptedKeyBytes);
121 SecretKey key = new SecretKeySpec(keyBytes, 0, keyBytes.length, "AES");
122
123 byte[] ivBytes = Base64.getDecoder().decode(ivBase64);
124 IvParameterSpec iv = new IvParameterSpec(ivBytes);
125
126 byte[] encryptedLicenseJsonBytes = Base64.getDecoder().decode(encryptedJson);
127
128 String algorithm = "AES/CBC/PKCS5Padding";
129 Cipher cipher = Cipher.getInstance(algorithm);
130 cipher.init(Cipher.DECRYPT_MODE, key, iv);
131 byte[] licenseJsonBytes = cipher.doFinal(encryptedLicenseJsonBytes);
132
133 return new String(licenseJsonBytes, StandardCharsets.UTF_8);
134 }
135
136 private PublicKey getPublicKey() throws InvalidKeySpecException, NoSuchAlgorithmException {
137
138 String publicKeyString = """
139 -----BEGIN PUBLIC KEY-----
140 MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwIKulLyaLQ2WeO0gIW2G
141 3jQqny3Y/7VUevBKulAEywaUbvECvZ4zGsnaMyACjXxMNkA1xU2WeSMP/WqC03wz
142 4d71liUeAqOYKMdGHXFN2qswWz/ufK6An0pTEqYaoiUfcwSBVo2ZTUcMQexScKaS
143 ghmaWqBHBYx+lBkVMcLG2PtLDRZbqgJvJr2QCzMSVUpEGGQEWs7YolIq46KCgqsq
144 pTdfrdqd59x6oRhTLegswzxwLyouvrKbRqKR2ZRbVvlGtUnnnlLDuhEfd0flMxuv
145 W98Siw6dWe1K3x45nDu5py2G9Q9fZS8/2KHUC6QcLLstLIoPnZjCl9Lcur1U6s9N
146 f5aLI9mwMfmSJsoVOuwx2/MC98uHvPoPbG4ZjiT0aaGg4JccTGD6pssDA35zPhkk
147 1l6wktEYtyF2A7zjzuFxioQz8fHBzIbHPCxzu4S2gh3qOVFf7c9COmX9MsnB70o2
148 EZ1rxlFIJ7937IGJNwWOQuiMKTpEeT6BwTdQNZQPqCUGvZ5eEjhrm57yCF4zuyrt
149 AR8DG7ahK2YAarADHRyxTuxH1qY7E5/CTQKYk9tIYsV4O05CKj7B8rBMtjVNjb4b
150 d7JwPW43Z3J6jo/gLlVdGSPg8vQDNVLl6sdDM4Pm1eJEzgR2JlqXDCRDUGNNsXH2
151 qt9Ru8ykX7PAfF2Q3/qg1jkCAwEAAQ==
152 -----END PUBLIC KEY-----
153 """;
154
155 publicKeyString = publicKeyString.replaceAll("-----BEGIN PUBLIC KEY-----", "").replaceAll("-----END PUBLIC KEY-----", "").replaceAll("\\s", "");
156 byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyString);
157
158 KeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
159 KeyFactory keyFactory = KeyFactory.getInstance("RSA");
160 PublicKey publicKey = keyFactory.generatePublic(keySpec);
161
162 return publicKey;
163 }
164
165 private byte[] decryptKey(byte[] encryptedKeyBytes) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
166
167 PublicKey publicKey = getPublicKey();
168
169 Cipher decryptCipher = Cipher.getInstance("RSA");
170 decryptCipher.init(Cipher.DECRYPT_MODE, publicKey);
171
172 byte[] decryptedBytes = decryptCipher.doFinal(encryptedKeyBytes);
173
174 return decryptedBytes;
175 }
176
177 public class InvalidLicenseException extends Exception {
178
179 public InvalidLicenseException(String message) {
180 super(message);
181 }
182
183 public InvalidLicenseException(String message, Throwable cause) {
184 super(message, cause);
185 }
186
187 }
188}
String decryptLicenseString(String encryptedJson, String ivBase64, String encryptedKey, String version)
DecryptedLicenseResponse parseLicenseJSON(BoostLicenseResponse licenseResponse)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.