Go调用os/exec执行openssl命令报错但相同命令在bash下运行正常
Go调用openssl解密失败问题解决方案
核心原因
Go标准库的os/exec包执行命令时不会启动shell进程,所有传入的参数都会原样传递给目标程序,不需要加任何shell层面的转义符、包裹符。
你代码里给密码加的双引号是shell场景下用来包裹带特殊字符的参数用的,当你直接把带双引号的密码传给openssl时,openssl会把双引号也当成密码的一部分,自然就会解密失败,和你捕获到的bad decrypt错误完全匹配。
而你把cmd.String()打印的命令放到shell里运行时,shell会先自动把参数两侧的双引号去掉,再把剩下的内容传给openssl,所以能正常运行。
修复方案
把-pass对应的参数部分的双引号移除即可,修改后的代码如下:
if executable, ok := openssl[runtime.GOOS]; ok { // 仅修改pass参数部分,去掉原格式里的双引号 cmd := exec.Command(executable, "enc", "-d", "-salt", "-aes-256-cbc", "-md", "sha256", "-pass", fmt.Sprintf(`pass:%s`, Password), "-in", inFilename, "-out", outFilename) fmt.Println(cmd.String()) var out bytes.Buffer var stderr bytes.Buffer cmd.Stdout = &out cmd.Stderr = &stderr err := cmd.Run() if err != nil { fmt.Println(fmt.Sprint(err) + ": " + stderr.String()) log.Fatal(err) } fmt.Println("Result: " + out.String()) } else { log.Fatal(errors.New(fmt.Sprintf("OS %s not supported", runtime.GOOS))) }
注意事项
- 所有通过
exec.Command传递的参数都不需要加shell层面的转义,比如参数里有空格、特殊符号时,直接把完整内容作为单个参数传入即可,os/exec会自动处理参数分隔的逻辑 - 如果确实需要依赖shell的语法(比如管道、通配符匹配),可以显式调用shell,写法为
exec.Command("bash", "-c", "你的完整shell命令"),Windows下对应换成powershell和-Command参数
内容的提问来源于stack exchange,提问作者pgentili
相关产品推荐
相关产品推荐

