SoFunction
Updated on 2025-05-21

Using Java to implement code analysis of Navicat password encryption and decryption

During the daily development process, we sometimes need to process credential information saved by various software, such as database connection passwords. This article will explain how to use Java to encrypt and decrypt database passwords saved by Navicat.

1. Background introduction

Navicat is a powerful database management tool that supports multiple database systems. In order to protect the user's database credentials, Navicat encrypts the password entered by the user. This article is based on the AES encryption algorithm used in Navicat 12 and later, as well as the Blowfish encryption algorithm used in Navicat 11 and previous versions, showing how to implement the encryption and decryption of these passwords through Java code.

2. Environmental preparation

Make sure that your development environment is configured with Java and that the necessary security libraries are introduced to support encryption operations. For this tutorial, we will use the JDK-ownedBag.

3. Code analysis

Encryption logic

  • AES encryption (for Navicat 12 and above): Use fixed key and initialization vector (IV).
  • Blowfish encryption (for Navicat 11 and below): Also using fixed keys and IVs, but the encryption process includes a step XOR operation.

Decryption logic

The decryption logic is divided into two situations: AES decryption and Blowfish decryption. For details, please refer to the above code snippet.decryptAESanddecryptBlowfishmethod.

4. Core code display

package ;
import ;
import ;
import ;
import ;
import ;
import ;
/**
 * @author albert_luo@
 * @version 1.0
 * @description: TODO
 * @date 04 Apr 2025 00:29
 */
public class NavicatPasswordUtil {
    public static void main(String[] args) throws Exception {
        // Create NavicatPasswordUtil instance        NavicatPasswordUtil passwordUtil = new NavicatPasswordUtil();
        // Password string to be decrypted        String encryptedPassword = "30A228E829283FEA8540DA18D2B6A302";
        // Decrypt Navicat 12 and later        String decryptedPassword = (encryptedPassword, NavicatVersion.VERSION_12);
        // Regular replacement control characters (such as ringing, backspace, etc.)        decryptedPassword = ("\\p{Cntrl}", "");
        // The output decrypted plaintext result is shiguang        ("Decrypted password: " + decryptedPassword);
    }
    // AES encryption key    private static final String AES_KEY = "libcckeylibcckey";
    // AES encryption vector    private static final String AES_IV = "libcciv libcciv ";
    // Blowfish encryption key    private static final String BLOWFISH_KEY = "3DC5CA39";
    // Blowfish encryption vector    private static final String BLOWFISH_IV = "d9c7c3c8870d64bd";
    /**
      * Encryption password
      *
      * @param plaintextPassword
      * @param navicatVersion encrypted version (NavicatVersion.VERSION_11 or NavicatVersion.VERSION_12)
      * @return Encrypted ciphertext password
      * @throws Exception What may be thrown during encryption
      */
    public String encryptPassword(String plaintextPassword, NavicatVersion navicatVersion) throws Exception {
        switch (navicatVersion) {
            case VERSION_11:
                return encryptBlowfish(plaintextPassword);
            case VERSION_12:
                return encryptAES(plaintextPassword);
            default:
                throw new IllegalArgumentException("Unsupported Navicat version");
        }
    }
    /**
      * Decrypt password
      *
      * @param encryptedPassword ciphertext password
      * @param navicatVersion decrypted version (NavicatVersion.VERSION_11 or NavicatVersion.VERSION_12)
      * @return The decrypted plaintext password
      * @throws Exception What may be thrown during decryption
      */
    public String decryptPassword(String encryptedPassword, NavicatVersion navicatVersion) throws Exception {
        switch (navicatVersion) {
            case VERSION_11:
                return decryptBlowfish(encryptedPassword);
            case VERSION_12:
                return decryptAES(encryptedPassword);
            default:
                throw new IllegalArgumentException("Unsupported Navicat version");
        }
    }
    /**
      * Encrypt password with Blowfish (for Navicat 11 and previous versions)
      *
      * @param plaintextPassword
      * @return Encrypted ciphertext password
      * @throws Exception What may be thrown during encryption
      */
    private String encryptBlowfish(String plaintextPassword) throws Exception {
        byte[] iv = hexStringToByteArray(BLOWFISH_IV);
        byte[] key = hashToBytes(BLOWFISH_KEY);
        int round = () / 8;
        int leftLength = () % 8;
        StringBuilder encryptedResult = new StringBuilder();
        byte[] currentVector = ();
        Cipher cipher = ("Blowfish/ECB/NoPadding");
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "Blowfish");
        (Cipher.ENCRYPT_MODE, secretKeySpec);
        for (int i = 0; i < round; i++) {
            byte[] block = xorBytes((i * 8, (i + 1) * 8).getBytes(), currentVector);
            byte[] encryptedBlock = (block);
            currentVector = xorBytes(currentVector, encryptedBlock);
            (bytesToHex(encryptedBlock));
        }
        if (leftLength > 0) {
            currentVector = (currentVector);
            byte[] block = xorBytes((round * 8).getBytes(), currentVector);
            (bytesToHex(block));
        }
        return ().toUpperCase();
    }
    /**
      * Encrypt password with AES (for Navicat 12 and later)
      *
      * @param plaintextPassword
      * @return Encrypted ciphertext password
      * @throws Exception What may be thrown during encryption
      */
    private String encryptAES(String plaintextPassword) throws Exception {
        byte[] iv = AES_IV.getBytes();
        byte[] key = AES_KEY.getBytes();
        Cipher cipher = ("AES/CBC/NoPadding");
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        (Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] encryptedResult = (());
        return bytesToHex(encryptedResult).toUpperCase();
    }
    /**
      * Use Blowfish to decrypt passwords (for Navicat 11 and previous versions)
      *
      * @param encryptedPassword ciphertext password
      * @return The decrypted plaintext password
      * @throws Exception What may be thrown during decryption
      */
    private String decryptBlowfish(String encryptedPassword) throws Exception {
        byte[] iv = hexStringToByteArray(BLOWFISH_IV);
        byte[] key = hashToBytes(BLOWFISH_KEY);
        byte[] encryptedBytes = hexStringToByteArray(());
        int round =  / 8;
        int leftLength =  % 8;
        StringBuilder decryptedResult = new StringBuilder();
        byte[] currentVector = ();
        Cipher cipher = ("Blowfish/ECB/NoPadding");
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "Blowfish");
        (Cipher.DECRYPT_MODE, secretKeySpec);
        for (int i = 0; i < round; i++) {
            byte[] encryptedBlock = (encryptedBytes, i * 8, (i + 1) * 8);
            byte[] decryptedBlock = xorBytes((encryptedBlock), currentVector);
            currentVector = xorBytes(currentVector, encryptedBlock);
            (new String(decryptedBlock));
        }
        if (leftLength > 0) {
            currentVector = (currentVector);
            byte[] block = (encryptedBytes, round * 8, round * 8 + leftLength);
            (new String(xorBytes(block, currentVector), StandardCharsets.UTF_8));
        }
        return ();
    }
    /**
      * Use AES to decrypt passwords (for Navicat 12 and later)
      *
      * @param encryptedPassword ciphertext password
      * @return The decrypted plaintext password
      * @throws Exception What may be thrown during decryption
      */
    private String decryptAES(String encryptedPassword) throws Exception {
        byte[] iv = AES_IV.getBytes();
        byte[] key = AES_KEY.getBytes();
        byte[] encryptedBytes = hexStringToByteArray(());
        Cipher cipher = ("AES/CBC/NoPadding");
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        (Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] decryptedResult = (encryptedBytes);
        return new String(decryptedResult);
    }
    /**
      * Exclusive OR operation on two byte arrays
      *
      * @param bytes1 First byte array
      * @param bytes2 Second byte array
      * @return Exorubic OR result byte array
      */
    private static byte[] xorBytes(byte[] bytes1, byte[] bytes2) {
        byte[] result = new byte[];
        for (int i = 0; i < ; i++) {
            result[i] = (byte) (bytes1[i] ^ bytes2[i]);
        }
        return result;
    }
    /**
      * Convert hexadecimal string to byte array
      *
      * @param hexString hex string
      * @return byte array
      */
    private static byte[] hexStringToByteArray(String hexString) {
        int len = ();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((((i), 16) << 4) + ((i + 1), 16));
        }
        return data;
    }
    /**
      * Hash string into byte array
      *
      * @param inputString input string
      * @return byte array after hash
      * @throws Exception May throw an exception during hashing
      */
    private static byte[] hashToBytes(String inputString) throws Exception {
        return ("SHA-1").digest(());
    }
    /**
      * Convert byte array to hexadecimal string
      *
      * @param byteArray byte array
      * @return Hexadecimal string
      */
    private static String bytesToHex(byte[] byteArray) {
        StringBuilder result = new StringBuilder();
        for (byte b : byteArray) {
            (("%02X", b));
        }
        return ();
    }
}
/**
  * Navicat version enumeration
  */
enum NavicatVersion {
    VERSION_11,
    VERSION_12
}
 

5. Summary

Through this article, we have learned how to use the Java language to encrypt and decrypt the database password saved by Navicat. This not only helps to deepen the understanding of encryption technology, but also provides a reference solution for dealing with similar requirements in actual projects. It should be noted that in real application scenarios, best security practices should be followed, such as regularly changing keys, avoiding hard-coded sensitive information, etc.

I hope this blog can help readers better understand and apply encryption technology in Java. If you want to have an in-depth understanding, it is recommended to try modifying and running the above code and observe the output results under different parameter settings.

This is the end of this article about using Java to implement code analysis of Navicat password encryption and decryption. For more related Java Navicat password content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!