├── .gitignore ├── Readme.md ├── go.mod ├── go.sum └── main.go /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Binaries for programs and plugins 3 | *.exe 4 | *.exe~ 5 | *.dll 6 | *.so 7 | *.dylib 8 | NaviPassRead 9 | # Test binary, built with `go test -c` 10 | *.test 11 | 12 | # Output of the go coverage tool, specifically when used with LiteIDE 13 | *.out 14 | 15 | # Dependency directories (remove the comment below to include it) 16 | # vendor/ -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Navicat 連線密碼查尋 2 | 將連線記錄中的連線密碼解碼 3 | 4 | # 適用版本 5 | Navicat 12 6 | 7 | # 使用方式 8 | 先啟動Navicat,並將連線設定匯出成*.ncx檔案(Navicat預設檔案), 9 | 執行命令 10 | ``` 11 | NaviPassRead -f [檔案路徑] 12 | ``` 13 | 檔案路徑預設為 ./navi.ncx 14 | 15 | # 輸出範例 16 | ``` 17 | [ 18 | { 19 | "ConnType":"MYSQL", 20 | "ConnectionName":"music", 21 | "Host":"localhost", 22 | "Password":"55688", 23 | "Port":"3306", 24 | "SSH_Host":"123.45.67.89", 25 | "SSH_UserName":"bob", 26 | "SSH_Password":"bobbobobo", 27 | "ServiceProvider":"Default", 28 | "UserName":"bob" 29 | }, 30 | { 31 | "ConnType":"MYSQL", 32 | "ConnectionName":"GCP", 33 | "Host":"88.77.66.55", 34 | "Password":"password123", 35 | "Port":"3306", 36 | "SSH_Host":"", 37 | "SSH_UserName":"", 38 | "SSH_Password":"", 39 | "ServiceProvider":"GoogleCloud", 40 | "UserName":"alice" 41 | } 42 | ] 43 | 44 | ``` 45 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/dalconan/NaviPassRead 2 | 3 | go 1.14 4 | 5 | require github.com/forgoer/openssl v0.0.0-20200331032942-ad9f8d57d8b1 // indirect 6 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/Luzifer/go-openssl/v3 v3.1.0 h1:QqKqo6kYXGGUsvtUoCpRZm8lHw+jDfhbzr36gVj+/gw= 2 | github.com/Luzifer/go-openssl/v3 v3.1.0/go.mod h1:liy3FXuuS8hfDlYh1T+l78AwQ/NjZflJz0NDvjKhwDs= 3 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/forgoer/openssl v0.0.0-20200331032942-ad9f8d57d8b1 h1:KC0gMm3q6pgXwfwMDx36ntHIB/B+ardzsa2SgRcdYdY= 5 | github.com/forgoer/openssl v0.0.0-20200331032942-ad9f8d57d8b1/go.mod h1:NMVFOzYeLVR7UiGTxsa+A21nrERTZ3Rv2JHDPcJpDyI= 6 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 7 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 8 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 9 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 10 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 11 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/hex" 5 | "encoding/json" 6 | "encoding/xml" 7 | "flag" 8 | "fmt" 9 | "github.com/forgoer/openssl" 10 | "io/ioutil" 11 | "os" 12 | ) 13 | 14 | type NaviConnections struct { 15 | XMLName xml.Name `xml:"Connections"` 16 | Connection []NaviConnection `xml:"Connection"` 17 | } 18 | 19 | type NaviConnection struct { 20 | ConnectionName string `xml:"ConnectionName,attr"` 21 | ConnType string `xml:"ConnType,attr"` 22 | ServiceProvider string `xml:"ServiceProvider,attr"` 23 | Host string `xml:"Host,attr"` 24 | Port string `xml:"Port,attr"` 25 | UserName string `xml:"UserName,attr"` 26 | Password string `xml:"Password,attr"` 27 | SSH_Host string `xml:"SSH_Host,attr"` 28 | SSH_UserName string `xml:"SSH_UserName,attr"` 29 | SSH_Password string `xml:"SSH_Password,attr"` 30 | } 31 | 32 | func decodepwd(pwd string) (string, error) { 33 | aesKey := []byte("libcckeylibcckey") 34 | aesIV := []byte("libcciv libcciv ") 35 | passDecode, err := hex.DecodeString(pwd) 36 | if err != nil { 37 | return "", err 38 | } 39 | dec, err := openssl.AesCBCDecrypt(passDecode, aesKey, aesIV, openssl.PKCS5_PADDING) 40 | if err != nil { 41 | return "", err 42 | } 43 | return string(dec), nil 44 | } 45 | 46 | func main() { 47 | var filePath string 48 | flag.StringVar(&filePath, "f", "./navi.ncx", "navicat export file") 49 | flag.Parse() 50 | file, err := os.Open(filePath) // For read access. 51 | 52 | if err != nil { 53 | fmt.Printf("file can't open. error: %s", err) 54 | return 55 | } 56 | defer file.Close() 57 | data, err := ioutil.ReadAll(file) 58 | 59 | if err != nil { 60 | fmt.Printf("error: %s", err) 61 | return 62 | } 63 | navis := NaviConnections{} 64 | err = xml.Unmarshal(data, &navis) 65 | if err != nil { 66 | fmt.Printf("xml parser error: %v", err) 67 | return 68 | } 69 | connectionData := []map[string]string{} 70 | for _, e := range navis.Connection { 71 | output := make(map[string]string) 72 | 73 | output["ConnectionName"] = e.ConnectionName 74 | output["ConnType"] = e.ConnType 75 | output["ServiceProvider"] = e.ServiceProvider 76 | output["Host"] = e.Host 77 | output["Port"] = e.Port 78 | output["UserName"] = e.UserName 79 | //decode password 80 | output["Password"] = "" 81 | output["Password"], err = decodepwd(e.Password) 82 | if err != nil { 83 | fmt.Printf("Password parser error: %s", err) 84 | return 85 | } 86 | output["SSH_Host"] = e.SSH_Host 87 | output["SSH_UserName"] = e.SSH_UserName 88 | output["SSH_Password"] = "" 89 | if e.SSH_Password != "" { 90 | output["SSH_Password"], err = decodepwd(e.SSH_Password) 91 | if err != nil { 92 | fmt.Printf("Password parser error: %s", err) 93 | return 94 | } 95 | } 96 | 97 | connectionData = append(connectionData, output) 98 | } 99 | 100 | jsonStr, err := json.Marshal(connectionData) 101 | 102 | if err != nil { 103 | fmt.Println(" ToJson err: ", err) 104 | } 105 | 106 | fmt.Println(string(jsonStr)) 107 | 108 | } 109 | --------------------------------------------------------------------------------