Tcl exec调用OpenSSL:短字符串解密返回空问题求助
Tcl调用OpenSSL时短字符串解密空值的优化解决方法
问题场景
最初使用echo管道传递文本变量给OpenSSL,代码如下:
set lines [exec echo $tte | openssl enc -a -$cipher -md $digest -nosalt -pbkdf2 -pass pass:$key]
因echo存在长度限制,改用Here String(<<)重定向输入:
set lines [exec openssl enc -a -$cipher -md $digest -nosalt -pbkdf2 -pass pass:$key -- << $tte]
解密时添加-d参数即可。但近期发现短字符串解密时OpenSSL返回空值,调试确认:
- 移除密文中的盐值、哈希指引等额外信息后解密正常
- 两种输入方式下传入的文本哈希值完全一致
当前临时方案是判断字符串长度>1024时用<<,否则用echo,需要更简洁可靠的替代方案。
问题根源
echo默认会在输出末尾添加换行符,而Here String传递短字符串时,若原字符串无换行,OpenSSL可能因输入格式不符合预期(比如认为输入未结束)返回空值,本质是两种输入方式的换行符差异导致OpenSSL处理逻辑不一致。
优化方案
方案1:统一使用Here String,补全换行符
给传递的字符串末尾添加换行符,模拟echo的输出格式,消除格式差异:
# 加密代码 set lines [exec openssl enc -a -$cipher -md $digest -nosalt -pbkdf2 -pass pass:$key -- << "${tte}\n"] # 解密代码 set lines [exec openssl enc -d -a -$cipher -md $digest -nosalt -pbkdf2 -pass pass:$key -- << "${tte}\n"]
此方案无需分支判断,统一输入格式后,短字符串解密可正常返回结果。
方案2:用Tcl管道直接写入数据(推荐)
通过Tcl的open命令创建管道,直接将变量内容写入OpenSSL的标准输入,完全绕过shell的echo或重定向逻辑,彻底避免格式和长度问题:
# 加密函数 proc encrypt_text {tte cipher digest key} { set cmd "openssl enc -a -$cipher -md $digest -nosalt -pbkdf2 -pass pass:$key --" set pipe [open "|$cmd" w+] puts $pipe $tte flush $pipe close $pipe return [read $pipe] } # 解密函数 proc decrypt_text {tte cipher digest key} { set cmd "openssl enc -d -a -$cipher -md $digest -nosalt -pbkdf2 -pass pass:$key --" set pipe [open "|$cmd" w+] puts $pipe $tte flush $pipe close $pipe return [read $pipe] }
这种方式直接控制输入内容,不受shell行为影响,无论字符串长短都能稳定处理,同时简化了代码逻辑。
内容的提问来源于stack exchange,提问作者dana
相关产品推荐
相关产品推荐

