07-15-2014 4:19 PM
Hello, I hope someone can help me out (or at least give me a hint) with this problem.
I have a requirement to encrypt files to send them to an external application. This is the schema of my problem:
1- The envelop/encryption of the file consists of a symmetric algorithm, using a generated key
2- This generated key is encrypted with the public key(Asymmetric algorithm) of this external application (I have the respective certificate to do this).
3- All this information is sent respecting the PKCS#7 format. This means that I can use any algorithm for the encryption that is supported by this format, like AES-256-CBC, AES-128-CBC, etc...
Also, I was supplied with a sample code of this process. Is written in java, using bouncy castle:
public byte[] envelop(InputStream inputFile, InputStream certif)
throws IOException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException, CMSException {
X509Certificate cert = null;
//obtiene los datos del archivo a encriptar
int sizecontent = inputFile.available();
byte[] contentbytes = new byte[sizecontent];
inputFile.read(contentbytes, 0, sizecontent);
inputFile.close();
//obtiene el certificado de IB
CertificateFactory cf = CertificateFactory.getInstance("X.509");
cert = (X509Certificate) cf.generateCertificate(certif);
certif.close();
//Ensobra el archivo utilizando AES256_CBC con 128 bits
String algorithm = CMSEnvelopedDataGenerator.AES256_CBC;
int keysize = 128; // bits
CMSEnvelopedDataGenerator fact = new CMSEnvelopedDataGenerator();
//agrega el certificado al sobre
fact.addKeyTransRecipient(cert);
CMSProcessableByteArray content = new CMSProcessableByteArray(contentbytes);
//encripta
CMSEnvelopedData envdata = fact.generate(content, algorithm, keysize, "BC");
//devuelve el resultado
byte[] enveloped = envdata.getEncoded();
return enveloped;
}
I found some information about the CMSEnvelopedDataGenerator.generate(), and effectively, it generates a random key.
Also, I found this link where it explains how to do this with OpenSSL. (search "CMS (RSA + AES)").
Is it possible to achive this with ABAP?
I had tried with the FM SSF_KRN_ENVELOPE, but it seems to not resolve my problem.
Thank you in advance.
Regards.
--
German Guzelj
07-15-2014 11:41 PM
Hi,
you are lucky. PKCS#7 is basically only thing that is supported by ABAP AS. You also tried to use right FM SSF_KRN_ENVELOPE. What did not work? Check available documentation for SSF.
Cheers
07-15-2014 11:41 PM
Hi,
you are lucky. PKCS#7 is basically only thing that is supported by ABAP AS. You also tried to use right FM SSF_KRN_ENVELOPE. What did not work? Check available documentation for SSF.
Cheers
07-16-2014 12:43 AM
Martin, thank you for the response.
I already checked the available documentation, but in the envelope section you could find this:
5.6 Develope a Document
Note: LIBSASPECU, the SSF library that is shipped with every R/3 system does not support
enveloping and developing. An external security product must be used for that purpose.
And there is no example of how I can execute this FM.
Although this FM does not have many parameters, I still wondering how I have to populate them.
To be more specific, Where do I have to specify the certificate of the application (public key)?
What do I have to complete in str_pab, str_pab_password and recipient_list?
Again, thank you very much!
Regards.
--
German Guzelj
07-16-2014 4:50 AM
Hi,
I think that part of documentation is obsolete. SAP uses this to protect credit card details if stored in SAP. I don't think you need additional product for this but I am not 100% sure.
If you do "where used" for this FM you will see that it's used in method EXTERNAL_ENCYPTING of class CL_PCA_SECURITY. This may give you an idea how to call this FM. From top of my head you can define an application in table SSFARGS. Here you define which PSE with certificate will be used and corresponding options for output format and algorithms. You can use FM SSF_GET_PARAMETER to read these settings from this table for an application. In reciepient list you need to use values returned by SSF_GET_PARAMETER. Unless you protect PSE with password you don't have to populate STR_PAB_PASSWORD. STR_PAB comes from SSF_GET_PARAMETER.
You can also see how it's done in report SSF01.
Cheers
07-16-2014 7:54 AM
I believe you still need a security product, though you can use SAP NetWeaver Signle Sign-On. See the following:
Constraints on Using SSF - Digital Signatures and Encryption - SAP Library
-Michael
07-18-2014 10:48 AM
One doesn't need SAP NWSSO for SSF encryption at the ABAP server. SAP Cryptographic Library is enough.
-Klaus
07-18-2014 10:55 AM
Instead of SSF_KRN_ENVELOPE, you may call the newer function module SSFW_KRN_ENVELOPE. Unfortunately, also for that function module there is no documentation available which I could recommend. You may have a look the unit test of function group SSFW (report LSSFWT99) in order to understand how to call that function module.
-Klaus
07-18-2014 5:12 PM
Thanks for the information, I was not aware of that.
Unfortunately, this FM does not exists in the system. Maybe is just a matter of implementing a OSS note.
Anyway, I already made use of another FM (SSFW_KRN_SIGN, the newest version of SSF_KRN_SIGN I guess) which rescued me in another cryptographic problem.
This problem was solved with SSF_KRN_ENVELOPE (I will post the problem in another reply).
Regards.
07-23-2014 3:07 PM
Martin Voros wrote:
Hi,
I think that part of documentation is obsolete. SAP uses this to protect credit card details if stored in SAP. I don't think you need additional product for this but I am not 100% sure.
If you do "where used" for this FM you will see that it's used in method EXTERNAL_ENCYPTING of class CL_PCA_SECURITY. This may give you an idea how to call this FM. From top of my head you can define an application in table SSFARGS. Here you define which PSE with certificate will be used and corresponding options for output format and algorithms. You can use FM SSF_GET_PARAMETER to read these settings from this table for an application. In reciepient list you need to use values returned by SSF_GET_PARAMETER. Unless you protect PSE with password you don't have to populate STR_PAB_PASSWORD. STR_PAB comes from SSF_GET_PARAMETER.
You can also see how it's done in report SSF01.
Cheers
Martin! thanks for you answer.
Fortunally, I can find out how I have to excecute this FM.
The problem here was when I executed the FM SSF_GET_PARAMETER.
As you said, this FM returns the parameters of a SSF application (location of the pse, encryption algorithm, etc..), but what I realy needed were the parameters of the certificate that is included in that SSF application.
So, I resolve it in this way:
1- Call SSF_GET_PARAMETER to get the information of SSFA
2- Call SSFC_GET_CERTIFICATELIST to get the certificate list of that SSFA
3- Call SSFC_PARSE_CERTIFICATE for every certificate in the list of certificates.
The code is something like this:
*Read SSFA information
CALL FUNCTION 'SSF_GET_PARAMETER'
EXPORTING
application = 'SSFA'
IMPORTING
str_pab = str_pab
str_pab_password = str_pab_password
str_profileid = str_profileid
str_profile = str_profile
str_encralg = str_encralg
EXCEPTIONS
ssf_parameter_not_found = 1
OTHERS = 2.
*Read certificates included in SSFA
CALL FUNCTION 'SSFC_GET_CERTIFICATELIST'
EXPORTING
profile = str_profile
IMPORTING
certificatelist = lt_certificatelist.
*Here you can obtein the information of each certificate. In my case is just one
LOOP AT lt_certificatelist INTO lv_certificate.
CALL FUNCTION 'SSFC_PARSE_CERTIFICATE'
EXPORTING
certificate = lv_certificate
IMPORTING
subject = l_subject
issuer = l_issuer
serialno = l_serialno
validfrom = l_validfrom
validto = l_validto
algid = l_algid
fingerprint = l_fingerprint
summary = l_summary
all = l_all
EXCEPTIONS
ssf_krn_error = 1
ssf_krn_nomemory = 2
ssf_krn_nossflib = 3
ssf_krn_invalid_par = 4
OTHERS = 5.
ENDLOOP.
lw_recipient-id = l_subject
INSERT lw_recipient INTO TABLE lt_recipient.
*Finally, call the FM to encrypt the document:
CALL FUNCTION 'SSF_KRN_ENVELOPE'
EXPORTING
ostr_input_data_l = lv_bin_data_len
str_pab = str_pab
str_pab_password = str_pab_password
str_sym_encr_alg = 'AES128-CBC'
IMPORTING
ostr_enveloped_data_l = lv_enveloped_data_len
crc = lv_crc
TABLES
ostr_input_data = lt_bin_data
recipient_list = lt_recipient
ostr_enveloped_data = lt_enveloped_data
EXCEPTIONS
ssf_krn_error = 1
ssf_krn_noop = 2
ssf_krn_nomemory = 3
ssf_krn_opinv = 4
ssf_krn_nossflib = 5
ssf_krn_recipient_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.
I hope this can help anybody with the same problem.
Regards.
--
German Guzelj