使用subprocess调用OpenSSL解密字符串返回None的问题排查
使用subprocess调用OpenSSL解密字符串的问题
我尝试用subprocess调用OpenSSL,通过密码解密加密字符串。对应的Bash命令如下:
echo <my_secret> | openssl enc -d -pbkdf2 -base64 -aes-128-ctr -nopad -nosalt -k <my_decr_key>
但运行以下Python代码时,输出结果为None,请问正确的实现方式是什么?
import subprocess secret = "my_secret" decr = "my_decr_key" i = subprocess.Popen["echo", secret], stdout=subprocess.PIPE x = subprocess.run([ "openssl", "enc", "-d", "-pbkdf2", "-base64", "-aes-128-ctr", "-nopad", "-nosalt", "-k", decr], stdin=i.stdout, shell=True) print(x.stdout) # 输出:None
错误原因分析
- 语法错误:
subprocess.Popen["echo", secret]写法错误,应该用圆括号调用构造函数,即subprocess.Popen(["echo", secret], stdout=subprocess.PIPE)。 - 未捕获标准输出:
subprocess.run默认不会捕获stdout,必须指定stdout=subprocess.PIPE才能获取输出内容,否则x.stdout为None。 - shell=True参数错误:当设置
shell=True时,run的第一个参数应该是单个命令字符串,而不是列表,否则会导致参数解析异常。
正确实现方式
方式1:不依赖shell,管道连接两个进程
这种方式更安全(避免shell注入风险),完全用subprocess的管道机制实现:
import subprocess secret = "my_secret" decr = "my_decr_key" # 启动echo进程输出加密字符串(-n避免添加额外换行符,和Bash行为一致) echo_proc = subprocess.Popen(["echo", "-n", secret], stdout=subprocess.PIPE) # 启动openssl进程,从echo的输出读取输入,并捕获自身的输出和错误 openssl_result = subprocess.run( ["openssl", "enc", "-d", "-pbkdf2", "-base64", "-aes-128-ctr", "-nopad", "-nosalt", "-k", decr], stdin=echo_proc.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True # 以文本模式处理,直接返回字符串而非bytes ) # 输出结果 if openssl_result.returncode == 0: print("解密结果:", openssl_result.stdout) else: print("解密失败,错误信息:", openssl_result.stderr)
方式2:模拟Bash管道命令(使用shell=True)
如果想完全复刻Bash的管道写法,可以直接构造命令字符串:
import subprocess secret = "my_secret" decr = "my_decr_key" # 构造完整的Bash命令字符串 cmd = f'echo -n "{secret}" | openssl enc -d -pbkdf2 -base64 -aes-128-ctr -nopad -nosalt -k "{decr}"' # 执行命令并捕获输出 result = subprocess.run( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True ) # 输出结果 if result.returncode == 0: print("解密结果:", result.stdout) else: print("解密失败,错误信息:", result.stderr)
内容的提问来源于stack exchange,提问作者pl33gS
相关产品推荐
相关产品推荐

