ABAP上对字符串进行签密并调用上上签的合同模板列表接口
首先,上上签提供了这个工具,可以直接计算签名,便于开发验证,地址 上上签在线算签
接着,写个验证程序:
*&---------------------------------------------------------------------*
*& Report ZZZZZZ14
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT ZZZZZZ14.
DATA: lv_output TYPE string,
lv_input_x TYPE xstring,
lv_input TYPE string,
lt_recipient_list TYPE STANDARD TABLE OF ssfinfo,
ls_recipient_list LIKE LINE OF lt_recipient_list,
lv_crc TYPE ssfparms-ssfcrc.
DATA: lf_input_data TYPE xstring,
lf_signed_data TYPE xstring,
ls_signer TYPE ssfinfo, "ssfinfoext is tested by CL_SMIME
lt_signer TYPE TABLE OF ssfinfo, "ssfinfoext is tested by CL_SMIME
lf_crc TYPE ssfreturn,
lf_signer_name TYPE string,
lf_chain_data TYPE xstring,
lf_output_data TYPE xstring,
lf_inputv_data TYPE xstring,
ls_certificate TYPE ssfcertlin,
lt_certificates TYPE TABLE OF ssfcertlin,
lf_subject(256) TYPE c.
"原文
lv_input ='bestsign-client-id=1657177378014361480bestsign-sign-timestamp=1657789020295bestsign-signature-type=RSA256request-body=d41d8cd98f00b204e9800998ecf8427euri=/api/templates/v2'.
CALL FUNCTION'SCMS_STRING_TO_XSTRING'
EXPORTING
text = lv_input
IMPORTING
buffer = lv_input_x.
"签名
"ls_signer-id = 'CN=testRSA'.
ls_signer-id = 'CN=user3'. " 'CN=user1'."一般为证书域名
"ls_signer-profile = '/usr/sap/FED/DVEBMGS00/sec/TEMP_5065F3F487881EDD80D77C72184D8504.pse'.
ls_signer-profile = '/usr/sap/FED/DVEBMGS00/sec/user3.pse'.
APPEND ls_signer TO lt_signer.
CALL FUNCTION 'SSFW_KRN_SIGN'
EXPORTING
ssftoolkit ='SAPSECULIB'
str_format = 'PKCS1-V1.5'
b_inc_certs = ''
b_detached = 'X'
b_inenc =''
str_hashalg ='SHA256'"'SHA1'
str_chainfmt =''
ostr_input_data = lv_input_x
IMPORTING
ostr_signed_data = lf_signed_data
str_signer_name = lf_signer_name
*ostr_signer_keyid =
ostr_chain_data = lf_chain_data
crc = lf_crc
TABLES
signer = lt_signer
EXCEPTIONS
ssf_krn_error =1
ssf_krn_noop =2
ssf_krn_nomemory =3
ssf_krn_opinv =4
ssf_krn_nossflib =5
ssf_krn_signer_list_error =6
ssf_krn_input_data_error =7
ssf_krn_invalid_par =8
ssf_krn_invalid_parlen =9
ssf_fb_input_parameter_error =10
OTHERS = 11.
data: lv_encoded type string.
CALL FUNCTION 'SCMS_BASE64_ENCODE_STR'
EXPORTING
INPUT = lf_signed_data
IMPORTING
OUTPUT = lv_encoded.
WRITE: / lv_encoded.
PERFORM show_data USING lf_signed_data.
CALL METHOD cl_http_utility=>escape_url
EXPORTING
unescaped = lv_encoded
RECEIVING
escaped = lv_encoded.
WRITE: / lv_encoded.
!!!这里产生的lv_encoded跟上上签工具里面生成的一样,到这里就ok了。
有几点注意的:
a) 调用SSFW_KRN_SIGN函数,在lt_signer返回内表中,如果result值不为0,可能是23,26,28都有
如果是CN=XXX 传入不正确,result = 26; SM21 Tcode中能看到:
SSF_KRN_DEVELOPE: Kernel Error 209 Occurred
22:41:21 DIA 007 200 UCHEQ247 SE38 RD 3 SSFW_KRN_ENVELOPE: Function Returned 9
22:41:21 DIA 007 200 UCHEQ247 SE38 RD 4 SSF: Sign Return Code 026
22:41:23 DIA 007 200 UCHEQ247 SE38 RD 2 SSF_KRN_DEVELOPE: Kernel Error 209 Occurred
如果是pse文件不对, result = 28;SM21 Tcode中能看到:
22:39:09 DIA 007 200 UCHEQ247 SE38 RD 3 SSFW_KRN_ENVELOPE: Function Returned 23
22:39:11 DIA 007 200 UCHEQ247 SE38 RD 2 SSF_KRN_DEVELOPE: Kernel Error 209 Occurred
2. 加密与签名是不一样的,用公钥加密,是用于传输秘密数据,传输过程的数据进行加密;私钥用于把数据进行签名,然后传输到对方系统,对方系统收到签名(sign)后验证传输的数据有没有被篡改。
3. SAP标准有个程序:SSF01 se38执行这个程序,刚开始看的一头雾水,其实也简单,前提就是你把私钥放到pse文件。
4. 在这位大师的连接中,有个function group: ssfw,其中有两个方法的确可以参考下
https://blog.csdn.net/xiefireworks/article/details/1248091615
5. 比较遗憾的是,用sm69建好命令行后,加密报错,不过现在用不着,也不去研究他了。