curl - OpenSSL 错误 error:0308010C:数字信封例程::不支持

pla*_*irt 42 windows curl openssl pkcs#12

我尝试在Windows 上使用curl 来发布时间戳请求。需要认证,所以我使用p12文件。我收到错误消息,但 p12 文件的密码是正确的。

命令:

curl --insecure --cert-type P12 --cert my.p12:mypassword -X POST -d @mytest.req <myTSURL>
Run Code Online (Sandbox Code Playgroud)

错误信息:

curl: (58) 无法解析 PKCS12 文件,检查密码,OpenSSL 错误 error:0308010C:数字信封例程::不支持

卷曲-V

curl 7.83.1 (x86_64-pc-win32) libcurl/7.83.1 OpenSSL/3.0.2 (Schannel) zlib/1.2.12 brotli/1.0.9 libidn2/2.3.2 libssh2/1.10.0 nghttp2/1.47.0 ngtcp2/0.5.0 nghttp3/0.4.1 libgsasl/1.10.0
Release-Date: 2022-05-11
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli gsasl HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL SSPI TLS-SRP UnixSocket
Run Code Online (Sandbox Code Playgroud)

dav*_*085 74

Meta:这并不是真正的编程或开发,在超级用户或 security.SX 上可能会更好,但随着 OpenSSL 3.0 的传播,这个问题可能会变得更加普遍,我想得到答案。

OpenSSL 3.0.x(及更高版本)默认情况下不支持旧的/不安全的算法,但直到最近,大多数创建 PKCS12 的软件(包括 OpenSSL 1.xx)都对 certbag 使用这种算法,即 PKCS12 定义的算法使用 40 位 RC2(通常缩写为 RC2-40)的 PBE,有些至少有时仍然这样做,例如默认情况下的 Windows 10 证书导出对话框。要检查此操作(已修复)

openssl pkcs12 -in my.p12 -info -nokeys -nocerts 
# in 3.x.x add -provider legacy -provider default or just -legacy
# to avoid prompt use -password or -passin, see man pages
Run Code Online (Sandbox Code Playgroud)

我预计输出将包括

PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Run Code Online (Sandbox Code Playgroud)

查看您的curl 是否有指定OpenSSL 3.0.x 提供程序的选项,如果有,请指定(固定)“旧版”和“默认”。否则,将你的 pkcs12 转换为(固定三次)

# in 3.x.x
openssl pkcs12 -in old -nodes -provider legacy -provider default -out temp && openssl pkcs12 -in temp -export -out new
# or simpler
openssl pkcs12 -in old -nodes -legacy -out temp && openssl pkcs12 -in temp -export -out new

# in 1.x.x
openssl pkcs12 -in old -nodes -out temp && openssl pkcs12 -in temp -export -descert -out new 

# and in either case securely delete temp; on systems with a memory tmpfs, 
# typically /tmp, putting the file there can help assure this

# IFF 'old' was created by software that put the keybag before the certbag,
# which you can infer from the order displayed by pkcs12 -info,
# you can skip the temp file and pipe directly from one openssl to the other
# compare /sf/ask/3812882811/ found by @PiotrDobrogost
Run Code Online (Sandbox Code Playgroud)

转换会丢失现有文件中设置的任何“友好名称”。对于curl,可能还有大多数其他程序,这并不重要,但如果您想将同一个文件与友好名称确实重要的内容一起使用,请添加-name $name-export部分。

  • 输出为:`MAC:sha1,迭代 1024 MAC 长度:20,盐长度:20 PKCS7 数据屏蔽密钥包:pbeWithSHA1And3-KeyTripleDES-CBC,迭代 1024 PKCS7 加密数据:pbeWithSHA1And40BitRC2-CBC,迭代 1024 输出密钥和证书时出错 B00E0000:错误:0308010C:数字信封例程:inner_evp_generic_fetch:不支持:crypto \ evp \ evp_fetch.c:349:全局默认库上下文,算法(RC2-40-CBC:0),属性()'` (2认同)
  • @user3677636:证书实际上并不需要加密,因为公钥加密的要点是公钥和证书可以是公开的。因此,RC2-40 实际上并不是一个漏洞,但它是一个缺陷:加密看起来很愚蠢,但做得很糟糕。更好的选择是完全不加密,“openssl”可以使用“-certpbe NONE”进行加密,但其他软件可能不会,或者使用传统上用于密钥包的相同 PBE-SHA1-3DES,这就是我的所有命令上面的做法(3.0.x 默认情况下使用它,而 1.xx 与 `-descert` 执行相同的操作,尽管说 `des` 而不是 `3des` 或 `tdes` 等) (2认同)

bob*_*mcn 30

我在使用 OpenVPN 时遇到了同样的错误。我可以通过在 /etc/ssl/openssl.cnf 配置文件中添加或取消注释以下行来修复它:

   openssl_conf = openssl_init
   
   [openssl_init]
   providers = provider_sect
   
   [provider_sect]
   default = default_sect
   legacy = legacy_sect
   
   [default_sect]
   activate = 1
   
   [legacy_sect]
   activate = 1
Run Code Online (Sandbox Code Playgroud)

这是基于OpenSSL WIKI上的信息