如何在ABAP中使用.CRT和.KEY文件调用HTTP端点?

4
我正在尝试从ABAP消耗一个端点,通过实例化一个if_http_client,使用cl_http_client=>create_by_url。当我不需要使用签名证书时,这个过程是有效的。通常我只需要使用STRUST交易包含证书。

但是对于这个特定的情况,我有两个证书文件:.crt.key。我能够从Postman获取端点,因为我可以将这些文件插入到设置->证书中:

enter image description here

那么,我该如何在ABAP中使用它?如何将这些文件插入我的http请求中?我应该从ABAP代码中传递它们,还是在STRUST或其他事务中进行配置?

您需要在STRUST中注册所有服务器的证书(.crt文件即可),以便从ABAP程序中访问它们。将它们注册到您使用CREATE_BY_URL的PSE(“SSL_ID”)中。例如,如果您使用SSL_ID“ANONYM”,则对应于“SSL客户端(匿名)”PSE。https://help.sap.com/docs/help/3e7fe88850cf4ee39d151949a990d8ca/0baa90ee1868411fae3ef92511988c63.html - Sandra Rossi
那么 .key 文件怎么办?我该如何插入它?我已经尝试将 .crt 文件插入 STRUST,但没有成功。 - rayashi
也许最好澄清一下呼叫需要什么。是1)控制SSL握手2)只需客户端证书即可满足SSL呼叫需要。还是3)只是匿名SSL呼叫和用户证书作为http头发送。 SAP ABAP无法控制SSL握手。其他两个是可以实现的。 - phil soady
1
你不能使用单个PEM或PFX文件吗?将你的CRT/KEY转换为PEM很容易,而且可以导入到STRUST中。 - Suncatcher
我该如何转换它们?我已经尝试过将它们连接成一个单独的 .pem 文件。 - rayashi
显示剩余2条评论
2个回答

2

编辑:重新修订答案以更好地解决问题,随着更多细节的出现。 读者注意:这是使用SSL的ABAP作为HTTP客户端(而不是服务器)。 这也是一个非典型的问题。在这里,SAP系统必须使用特定的客户端证书连接到另一个服务以建立SSL连接。这通常是在网络层管理的。

加载证书时,必须将其加载到客户端PSE区域中的STRUST中。

之前的想法(在编辑/重新修订之前)将证书作为标头发送,解释为选项3。

选项:

1)在ABAP中进行SSL握手。 尝试在ABAP中管理SSL握手很可能是不可能的。 SSL握手由sapcryptolib管理。

2)将客户端证书导入STRUST 到标准客户端PSE。请参阅下面的详细信息

3)使用xxxx.cer作为字符串并添加为Http标头 (如果选项2不起作用,则是最后的选择)

==============================================================

2) 选项2详情(最佳方式) 将您的证书导入Strust,在SSL客户端标准区域。

这里是一个实际案例的标准sap文档示例。 这是Dutsch工资单接口。使用私钥证书。 *.p12或*.pfx文件。私钥证书

https://help.sap.com/docs/ERP_HCM_SPV/491c29ac9232469bb257a2ba14ac290c/999ad0ce8bd24945b547584e776e9a4e.html

由于该类型的证书无法直接导入SAP,因此需要在操作系统级别使用sapgenpse将p12转换为pse文件。Strust不支持导入p12文件。

现在,ABAP调用使用在此步骤中创建的客户端身份。

 cl_http_client=>create_by_url(
            EXPORTING
              url                = 'url'           
              ssl_id             = 'CL_ID' "Ident created in step above  
            IMPORTING
              client             = lo_client       
          ).

或许更容易处理的方法是使用Sm59创建一个外部http地址并选择这个新创建的标识。

SM59 external destination

然后通过已创建的目标调用http客户端。

CALL METHOD cl_http_client=>create_by_destination
  EXPORTING
    destination              = lv_destination "the new sm59 destination 
  IMPORTING
    client                   = lo_http_client.

第三个选项的细节:(不是最理想的,假设被调用的服务支持它。) 当且仅当被调用的服务支持证书作为头时, 请注意,xxx.cer 相当于身份密钥。 仔细管理字符串。
数据:lo_client 类型 REF TO if_http_client。
cl_http_client=>create_by_url( EXPORTING url = 'url' ssl_id = 'ANONYM' "作为匿名 SSL 开始 SSL 握手 IMPORTING client = lo_client )。
"将实际标识作为HTTP头传递, "许多服务支持此方法。但是它们的解决方案通常 "特定于该服务。 "例如,微软翻译服务。 "期望用户订阅密钥作为一个标题。 'https://api-eur.cognitive.microsofttranslator.com/translate?api-version=3.0'
lo_client->request->set_header_field(
      EXPORTING
        name  = 'Client-Cert'    "Check HTTP header name with called Service docu
        value = '<cert> in string format'
    ).
    
    "lo_client->send( .. )
    "lo_client->receive( .. )

1
@SandraRossi Rayashi说他已经知道并使用了Strust来导入证书,包括服务器和客户端。如果可能的话,使用Anoym的想法是尝试将证书和密钥添加为特殊头部。如果您可以在Strust中导入证书捆绑包,那确实是解决方案。但是如何在Strust中做到这一点?这就是替代方法的整个重点。您只能在Strust中导入cert.而不能导入certificate key bundle。Rayashi正在询问有关密钥捆绑包的信息。这就是问题所在。您无法使用STRUST,现在该怎么办? - phil soady
@philsoady 我该如何从 .crt 和 .key 文件中获取客户端证书和客户端证书链? - rayashi
那个问题表明我误解了您想要实现的目标。 这意味着示例不是您想要的。只需使用STRUST将客户端证书导入到CLIENT PSE中即可。如果您没有清晰的要求来发送公钥和证书,则该计划是错误的。 - phil soady
你写的例子确实不是我想要的。我需要使用的 API 文档中并没有提到我应该在头部发送 Client-Cert 或者 Client-Cert-Chain。他们提供了一个 Python 示例代码,像这样 https://gist.github.com/hdiburla/d15712dfab9288d84e1edd5ff7f00452。 - rayashi
@SandraRossi,现在揭示如何将密钥对和证书导入STRUST的技巧。首先需要使用sapgenpse进行转换。 我以前从未使用过它...它确实澄清了解决此问题的最佳方法。 https://help.sap.com/docs/SAP_NETWEAVER_AS_ABAP_751_IP/e73bba71770e4c0ca5fb2a3c17e8e229/0d9ce63bab134b39a52e340255d7650c.html?version=7.51.13&locale=en-US - phil soady
显示剩余4条评论

1
使用 KeyStore Explorer 工具从客户端键和证书创建单个 pfx 文件。也可以使用该工具将客户端证书链放入其中。
在本地系统上使用 sapgenpse 命令从 pfx 文件创建 pse 文件:
sapgenpse import_p12 -p c:\client.pse c:\client.pfx

前往STRUST,在“环境” ->“SSL客户端身份”下创建自己的证书存储。我更喜欢这样做,以免混淆所有内容。然后返回STRUST并选择PSE ->导入,选择您的自定义pse文件。然后单击PSE ->另存为,并选择您的自定义身份。

将站点SSL证书添加到您的新身份。

您可以在SM59中尝试使用新的SSL客户端配置,并选择您的新SSL客户端身份。

以下是ABAP代码示例。

REPORT ZMKY_SSL_CLIENT.

 DATA: lo_client TYPE REF TO if_http_client,
       lv_code   TYPE i,
       lv_REASON type string.

   cl_http_client=>create_by_url(
     EXPORTING
       url                = 'https://mysslclienthost.com'
       ssl_id             = 'MYSSLC'      "Your SSL Client identity
     IMPORTING
       client             = lo_client
   ).

   lo_client->SEND( ).

   lo_client->RECEIVE( ).

   lo_client->RESPONSE->GET_STATUS( IMPORTING CODE = lv_code
                                    REASON         = lv_reason ).

   WRITE: lv_code, lv_reason.

1
这就是正确的答案。我之前尝试过,但是sapgenpse一直报错,说证书不完整。所以API提供商给了我那些文件,我使用了-r参数,这样就可以使用中间证书了。现在可以工作了。谢谢! - rayashi
现在您有了一个正确的 crt 文件,可以导入它了。 - phil soady

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接