DBクライアントツールとして皆大好き、DBeaver を使っていて設定したユーザ、パスワードを忘れてしまい
暗号化されたパスワードを参照したい時、どうしようと困ったことがある。
暗号のキーを知っていれば復号できる。以下、DBeaver内部にコードから知ることができて、
https://github.com/dbeaver/dbeaver/blob/57cec8ddfdbbf311261ebd0c7f957fdcd80a085f/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/app/DefaultSecureStorage.java#L31
どうやら、AES暗号、パディングは、PKCS5 みたいなので、
暗号化されたファイルのパスを与えて読み込ませて復号する処理のクラスを用意した。
DBeaver設定の接続情報ユーザ、パスワードを暗号化したファイルは、Windows のユーザディレクトリの以下の場所に、
C:\Users\${userName}\AppData\Roaming\DBeaverData\workspace6\General\.dbeaver
の下、
credentials-config.json が作成されているのでこれをこのクラスで処理する。
import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Map; import java.util.Scanner; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; /** * DBeaver credentials-config.json の解析 */ public class DbeaverParse{ private final byte[] LOCAL_KEY_CACHE = new byte[]{ -70, -69, 74, -97, 119, 74, -72, 83, -55, 108, 45, 101, 61, -2, 84, 74 }; private Path configpath; public DbeaverParse(String credentialsConfigPath) { configpath = Paths.get(credentialsConfigPath); } public String decrypt() throws InvalidAlgorithmParameterException, InvalidKeyException, IOException , NoSuchPaddingException, NoSuchAlgorithmException { byte[] contents = Files.readAllBytes(configpath); try (InputStream byteStream = new ByteArrayInputStream(contents)) { byte[] fileIv = new byte[16]; byteStream.read(fileIv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKey aes = new SecretKeySpec(LOCAL_KEY_CACHE, "AES"); cipher.init(Cipher.DECRYPT_MODE, aes, new IvParameterSpec(fileIv)); try(CipherInputStream cipherIn = new CipherInputStream(byteStream, cipher); Scanner scanner = new Scanner(cipherIn).useDelimiter("\\A")){ return scanner.hasNext() ? scanner.next() : ""; } } } public String prettyJsonString(String str) { try{ ObjectMapper mapper = new ObjectMapper(); return new ObjectMapper().writerWithDefaultPrettyPrinter() .writeValueAsString(mapper.readValue(str, Map.class)); }catch(JsonProcessingException e){ throw new RuntimeException(e.getMessage(), e); } } }
復号した結果Json文字列が、フラットで読みにくいかもしれないので、Jackson のJsonライブラリで、
整形できるようにしておく。
Jackson は、Maven で以下のように取得しておくと良いだろう
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.2.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.13.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.13.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.13.2</version> </dependency>
DbeaverParse の 呼び出し
try{ DbeaverParse dbeaverParse = new DbeaverParse("C:/Users/XXXX/AppData/Roaming/DBeaverData/workspace6/General/.dbeaver/credentials-config.json"); String json = dbeaverParse.decrypt(); String jsonPretty = dbeaverParse.prettyJsonString(json); System.out.println(jsonPretty); }catch(InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | NoSuchAlgorithmException | IOException e){ e.printStackTrace(); }
おそらくPythonでも書けるだろう。