这个问题具体针对明GW/MSYS这通常用作适用于 Windows 的 Git包裹。
解决方案是通过-subj
与领导争论//
(双正斜杠)然后使用\
(反斜杠)分隔键/值对。像这样:
"//O=Org\CN=Name"
然后这将神奇地传递给openssl
以预期的形式:
"/O=Org/CN=Name"
因此,要回答具体问题,您应该更改-subj
将脚本中的行添加到以下内容。
-subj "//C=GB\ST=someplace\L=Provo\O=Achme\CN=${FQDN}"
这应该就是您所需要的。
这是什么魔法?
对于那些好奇到底发生了什么的人,我可以解释这个谜团。原因是 MSYS 合理地假设包含斜杠的参数实际上是路径。当这些参数传递给尚未专门为 MSYS 编译的可执行文件时(例如openssl
在这种情况下)那么它会将 POSIX 路径转换为 Win32 路径 http://www.mingw.org/wiki/Posix_path_conversion。这种转换的规则相当复杂,因为 MSYS 尽力涵盖最常见的互操作场景。这也解释了为什么使用openssl
从 Windows 命令提示符(cmd.exe
)工作正常,因为没有进行神奇的转换。
您可以像这样测试转换。
$ cmd //c echo "/CN=Name"
"C:/Program Files (x86)/Git/CN=Name"
我们不能使用echo
MSYS 附带的可执行文件,因为它是为 MSYS 编译的,我们将使用echo
内置于cmd
。请注意,自从cmd
开关以/
(对于 Windows 命令很常见)我们需要用双斜杠来处理它。正如我们在输出中看到的,参数被扩展为 Windows 路径,原因就很清楚了openssl
确实声称Subject does not start with '/'.
.
让我们看看更多的转换。
$ cmd //c echo "//CN=Name"
/CN=Name
双斜杠使 MSYS 相信该参数是一个 Windows 风格的开关,这会导致剥离/
仅(无路径转换)。您可能会认为这样我们就可以使用斜杠来添加更多键/值对。让我们试试吧。
$ cmd //c echo "//O=Org/CN=Name"
//O=Org/CN=Name
突然,开头的双斜杠没有被删除。这是因为现在,在最初的双斜杠后面有一个斜杠,MSYS 认为我们正在引用 UNC 路径(例如 //server/path)。如果这被传递给openssl
它会跳过第一个键/值说Subject Attribute /O has no known NID, skipped
.
以下是相关规则MinGW 维基 http://www.mingw.org/wiki/Posix_path_conversion解释这种行为:
- An argument starting with 2 or more / is considered an escaped Windows style switch and will be passed with the leading / removed and all \ changed to /.
- 但如果 / 的前导块后面有一个 /,则该参数将被视为 UNC 路径,并且前导 / 不会被删除。
在这条规则中,我们可以看到可以用来创建我们想要的参数的方法。既然所有\
后面的论证以//
将被转换为普通/
。让我们尝试一下。
$ cmd //c echo "//O=Org\CN=Name"
/O=Org/CN=Name
正如我们所看到的,它确实有效。
希望这能稍微揭开魔法的神秘面纱。