inou/tools/decrypt/main.go

136 lines
3.0 KiB
Go

package main
import (
"bufio"
"encoding/json"
"flag"
"fmt"
"os"
"regexp"
"strings"
"inou/lib"
)
// Matches base64 strings (at least 20 chars to avoid false positives)
var base64Pattern = regexp.MustCompile(`[A-Za-z0-9+/]{20,}={0,2}`)
func main() {
jsonMode := flag.Bool("json", false, "Input is JSON, decrypt string values")
fileMode := flag.Bool("file", false, "Input is encrypted binary file")
flag.Parse()
if err := lib.Init(); err != nil {
fmt.Fprintf(os.Stderr, "Failed to initialize: %v\n", err)
os.Exit(1)
}
if *fileMode {
// Read all stdin as binary, decrypt, write to stdout
data, err := os.ReadFile("/dev/stdin")
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to read: %v\n", err)
os.Exit(1)
}
decrypted, err := lib.CryptoDecryptBytes(data)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to decrypt: %v\n", err)
os.Exit(1)
}
os.Stdout.Write(decrypted)
return
}
scanner := bufio.NewScanner(os.Stdin)
// Increase buffer for long lines
buf := make([]byte, 0, 1024*1024)
scanner.Buffer(buf, 10*1024*1024)
if *jsonMode {
// Read all input as JSON
var input strings.Builder
for scanner.Scan() {
input.WriteString(scanner.Text())
input.WriteString("\n")
}
decryptJSON(input.String())
} else {
// Line-by-line mode: find and decrypt base64 strings
for scanner.Scan() {
line := scanner.Text()
result := base64Pattern.ReplaceAllStringFunc(line, tryDecrypt)
fmt.Println(result)
}
}
if err := scanner.Err(); err != nil {
fmt.Fprintf(os.Stderr, "Error reading input: %v\n", err)
}
}
func tryDecrypt(s string) string {
decrypted := lib.CryptoDecrypt(s)
if decrypted == "" {
return s // Not encrypted or failed, keep original
}
return decrypted
}
func decryptJSON(input string) {
// Try as JSON array first
var arr []map[string]interface{}
if err := json.Unmarshal([]byte(input), &arr); err == nil {
for i := range arr {
decryptMap(arr[i])
}
output, _ := json.MarshalIndent(arr, "", " ")
fmt.Println(string(output))
return
}
// Try as single JSON object
var obj map[string]interface{}
if err := json.Unmarshal([]byte(input), &obj); err == nil {
decryptMap(obj)
output, _ := json.MarshalIndent(obj, "", " ")
fmt.Println(string(output))
return
}
// Fall back to line-by-line
for _, line := range strings.Split(input, "\n") {
result := base64Pattern.ReplaceAllStringFunc(line, tryDecrypt)
fmt.Println(result)
}
}
func decryptMap(m map[string]interface{}) {
for k, v := range m {
switch val := v.(type) {
case string:
if decrypted := lib.CryptoDecrypt(val); decrypted != "" {
m[k] = decrypted
}
case map[string]interface{}:
decryptMap(val)
case []interface{}:
decryptSlice(val)
}
}
}
func decryptSlice(s []interface{}) {
for i, v := range s {
switch val := v.(type) {
case string:
if decrypted := lib.CryptoDecrypt(val); decrypted != "" {
s[i] = decrypted
}
case map[string]interface{}:
decryptMap(val)
case []interface{}:
decryptSlice(val)
}
}
}