136 lines
3.0 KiB
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)
|
|
}
|
|
}
|
|
}
|