1. 问题的发生:

    以前创建了一个本地MySql数据库,连接上Navicat后就没再管。但前不久有个项目需要用到本地的数据库连接字符串,但由于忘记密码而无法更进一步时,才有了这个方法。仅供学习用哈!
  2. 前提:

    Navicat已连接
  3. 实现

    1. 导出数据库连接

      1. 打开Navicat,点击【文件 - 导出连接】
      2. 选择忘记密码的数据库以及导出地址
      3. 打开导出的文件
      4. 拷贝加密的密码(Password字段,如:FD6A72E7E05B8D7F01FCE049F4DD76EA)
    2. 解密

      1. 编写一个C#解密方法
      2. 代码可以直接使用
        using System;
        using System.Security.Cryptography;
        using System.Text;
        using System.Linq;
        using System.Diagnostics;
        using System.Numerics;
        
        namespace UnitTest
        {
        
        
            public class NavicatPassword
            {
                private int version = 0;
                private string aesKey = "libcckeylibcckey";
                private string aesIv = "libcciv libcciv ";
                private string blowString = "3DC5CA39";
                private byte[] blowKey;
                private byte[] blowIv;
        
                public NavicatPassword(int version = 12)
                {
                    this.version = version;
                    this.blowKey = Encoding.ASCII.GetBytes(HashFunction(this.blowString));
                    this.blowIv = HexStringToByteArray("d9c7c3c8870d64bd");
                }
        
                public string Encrypt(string input)
                {
                    string result = null;
                    switch (this.version)
                    {
                        case 11:
                            result = EncryptEleven(input);
                            break;
                        case 12:
                            result = EncryptTwelve(input);
                            break;
                        default:
                            break;
                    }
        
                    return result;
                }
        
                public string Decrypt(string input)
                {
                    string result = null;
                    switch (this.version)
                    {
                        case 11:
                            result = DecryptEleven(input);
                            break;
                        case 12:
                            result = DecryptTwelve(input);
                            break;
                        default:
                            break;
                    }
        
                    return result;
                }
        
                private string EncryptEleven(string input)
                {
                    byte[] inputBytes = Encoding.UTF8.GetBytes(input);
                    int round = inputBytes.Length / 8;
                    int leftLength = inputBytes.Length % 8;
                    byte[] result = new byte[inputBytes.Length];
                    byte[] currentVector = this.blowIv;
        
                    for (int i = 0; i < round; i++)
                    {
                        byte[] temp = EncryptBlock(XorBytes(inputBytes.Skip(i * 8).Take(8).ToArray(), currentVector));
                        currentVector = XorBytes(currentVector, temp);
                        Buffer.BlockCopy(temp, 0, result, i * 8, 8);
                    }
        
                    if (leftLength > 0)
                    {
                        currentVector = EncryptBlock(currentVector);
                        byte[] lastPart = XorBytes(inputBytes.Skip(round * 8).Take(leftLength).ToArray(), currentVector);
                        Buffer.BlockCopy(lastPart, 0, result, round * 8, leftLength);
                    }
        
                    return BitConverter.ToString(result).Replace("-", "").ToUpper();
                }
        
                private string EncryptTwelve(string input)
                {
                    using (Aes aes = Aes.Create())
                    {
                        aes.Key = Encoding.UTF8.GetBytes(this.aesKey);
                        aes.IV = Encoding.UTF8.GetBytes(this.aesIv);
                        using (ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
                        {
                            byte[] encrypted = encryptor.TransformFinalBlock(Encoding.UTF8.GetBytes(input), 0, input.Length);
                            return BitConverter.ToString(encrypted).Replace("-", "").ToUpper();
                        }
                    }
                }
        
                private string DecryptEleven(string input)
                {
                    byte[] inputBytes = HexStringToByteArray(input);
                    int round = inputBytes.Length / 8;
                    int leftLength = inputBytes.Length % 8;
                    byte[] result = new byte[inputBytes.Length];
                    byte[] currentVector = this.blowIv;
        
                    for (int i = 0; i < round; i++)
                    {
                        byte[] encryptedBlock = new byte[8];
                        Buffer.BlockCopy(inputBytes, i * 8, encryptedBlock, 0, 8);
                        byte[] temp = XorBytes(DecryptBlock(encryptedBlock), currentVector);
                        currentVector = XorBytes(currentVector, encryptedBlock);
                        Buffer.BlockCopy(temp, 0, result, i * 8, 8);
                    }
        
                    if (leftLength > 0)
                    {
                        currentVector = EncryptBlock(currentVector);
                        byte[] lastPart = XorBytes(inputBytes.Skip(round * 8).Take(leftLength).ToArray(), currentVector);
                        Buffer.BlockCopy(lastPart, 0, result, round * 8, leftLength);
                    }
        
                    return Encoding.UTF8.GetString(result);
                }
        
                private string DecryptTwelve(string input)
                {
                    byte[] inputBytes = HexStringToByteArray(input);
                    using (Aes aes = Aes.Create())
                    {
                        aes.Key = Encoding.UTF8.GetBytes(this.aesKey);
                        aes.IV = Encoding.UTF8.GetBytes(this.aesIv);
                        using (ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
                        {
                            byte[] decrypted = decryptor.TransformFinalBlock(inputBytes, 0, inputBytes.Length);
                            return Encoding.UTF8.GetString(decrypted);
                        }
                    }
                }
        
                private byte[] EncryptBlock(byte[] block)
                {
                    using (TripleDES tripleDES = TripleDES.Create())
                    {
                        tripleDES.Key = this.blowKey;
                        tripleDES.Mode = CipherMode.ECB;
                        tripleDES.Padding = PaddingMode.None;
                        using (ICryptoTransform encryptor = tripleDES.CreateEncryptor(tripleDES.Key, null))
                        {
                            return encryptor.TransformFinalBlock(block, 0, block.Length);
                        }
                    }
                }
        
                private byte[] DecryptBlock(byte[] block)
                {
                    using (TripleDES tripleDES = TripleDES.Create())
                    {
                        tripleDES.Key = this.blowKey;
                        tripleDES.Mode = CipherMode.ECB;
                        tripleDES.Padding = PaddingMode.None;
                        using (ICryptoTransform decryptor = tripleDES.CreateDecryptor(tripleDES.Key, null))
                        {
                            return decryptor.TransformFinalBlock(block, 0, block.Length);
                        }
                    }
                }
        
                private byte[] XorBytes(byte[] str1, byte[] str2)
                {
                    byte[] result = new byte[str1.Length];
                    for (int i = 0; i < str1.Length; i++)
                    {
                        result[i] = (byte)(str1[i] ^ str2[i]);
                    }
        
                    return result;
                }
        
                private static byte[] HexStringToByteArray(string hex)
                {
                    int numberChars = hex.Length;
                    byte[] bytes = new byte[numberChars / 2];
                    for (int i = 0; i < numberChars; i += 2)
                    {
                        bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
                    }
        
                    return bytes;
                }
        
                private static string HashFunction(string input)
                {
                    using (SHA1 sha1 = SHA1.Create())
                    {
                        byte[] hashBytes = sha1.ComputeHash(Encoding.ASCII.GetBytes(input));
                        StringBuilder sb = new StringBuilder();
                        foreach (byte b in hashBytes)
                        {
                            sb.Append(b.ToString("X2"));
                        }
        
                        return sb.ToString();
                    }
                }
            }
        }
        
      3. 引用此方法
        public void DoDecrypt()
        {
            NavicatPassword navicatPassword = new NavicatPassword(12);
        
            // 解密
            string decoded = navicatPassword.Decrypt("FD6A72E7E05B8D7F01FCE049F4DD76EA");
            Console.WriteLine(decoded);
        }
      4. 得出结果
    3. 参考文档

      “忘记了Navicat数据库密码?跟着这个指南一步步找回来!“_navicat查看数据库密码-CSDN博客
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐