Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Create base64 encoded digital signature form keystore with ABAP functions

Former Member
0 Kudos

Hi folks!

We face the following challenge: We have to create a base64 encoded digital signature from a keystore cert file using ABAP functions. Currently this features is implemented in Java using features of the java.security.* package (Java source code see below).

Question is: Has anybody got experiences on how to implement this using ABAP functions?

Where do we have to store the .cer file and are there any standard classes/methods and/or function modules we can use to read this file and get the private key from it?

Here comes the Java code snippet of the current implementation:

/**

  • Create a base64 encoded signature from data. returns null on error.

  • @param data

  • @return bae64 encoded signature or null

*/

private String sign(String data)

{

Signature signature;

try

{

// Read keystore

KeyStore ks = KeyStore.getInstance("JKS");

InputStream ksin = Thread.currentThread().getContextClassLoader().getResourceAsStream(KeyStoreFile);

ks.load(ksin, KeyStorePwd);

ksin.close();

// get private key from keystore

Key key = ks.getKey(KeyAlias, KeyAliasPwd);

// Create signature

signature = Signature.getInstance(Algorithm);

signature.initSign((PrivateKey)key);

}

catch (Exception e)

{

// read keystore: FileNotFoundException, IOException, KeyStoreException

// read key: NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException

return null;

}

try

{

signature.update(data.getBytes());

byte[] dataSignature = signature.sign(); // Get signature

return new String(Base64.encodeBase64(dataSignature)); // return base64-encoded signature

}

catch (Exception e)

{

System.err.println(e.toString());

}

return null;

}

Thanx for any hint in advance!!!!

Regards,

Volker

1 ACCEPTED SOLUTION

Former Member
0 Kudos

Hi Volker,

Here is a detailed example about converting Java Keystore in PKCS#12 format:

1) Generate keystore

keytool -genkey -keystore c:\temp\keys.jks -alias jorge -storepass 123456 -keypass 123456 -dname "CN=Jorge, OU=CSC, O=CSC

2) Export certificate in DER format

keytool -exportcert -keystore keys.jks -alias jorge -storepass 123456 -keypass 123456 -file cert.der

3) Export private key from keystore

a) Download ExportPrivateKey.zip from

http://www.anandsekar.com/wp-content/uploads/2006/01/ExportPrivateKey.zip

b) java -jar ExportPrivateKey.zip keys.jks JKS 123456 jorge key.pem

4) Download and extract openssl

5) convert certificate from DER to PEM

openssl x509 -inform DER -in cert.cer -outform PEM -out cert.pem

6) Concatenate text files cert.pem and key.pem in a new file keystore.pem with a text editor

7) Convert keystore in PEM format to PKCS12

openssl pkcs12 -export -in keystore.pem -out keystore.pfx

Other if useful: Convert only key from PEM to DER

openssl pkcs8 -inform PEM -nocrypt -in key.pem -outform DER -out key.der

Best regards,

Jorge

18 REPLIES 18

Former Member
0 Kudos

Hi Volker,

Digital signatures in ABAP are created with SSF functions. By default SAP systems have installed SAPSECULIB (only supports DSA) so you have to do nothing special to sign data. If you also want to create digital envelopes (encrypt data), you have to download and install SAP Crypto Lib (Supports DAS and RSA) from SAP Service Marketplace.

In ABAP you can only create PKCS7 signatures.

  • Certificates are managed with transaction STRUST.

- You will have to create a new PSE from your certificate (Public part and private key)

- Use executable sapgenpse.exe in /usr/sap/<SID>/SYS/exe/run

- Example to convert a PFX (Exported from internet explorer) file into a PSE from a command promt

sapgenpse import_p12 -p test.pse test.pfx

- Import this PSE in transaction STRUST

- All PSEs are in SAP directory /usr/sap/<SID>/DVEBMGSii/sec (ii - Instance Number)

  • SSF function module to sign data: SSF_KRN_SIGN or SSF_SIGN.

  • Function to convert data to Base 64: SCMS_BASE64_ENCODE / SCMS_BASE64_ENCODE_STR

Example report:

report zssf_test.


DATA: l_crc TYPE i,
      l_data TYPE text128,
      l_data_len TYPE i,

      lt_data_to_sign TYPE TABLE OF text128,


      l_signed_data_len TYPE i,
      lt_signed_data TYPE TABLE OF ssfbin,

      lt_data TYPE TABLE OF text128,


*     Signers
      lt_signers TYPE TABLE OF SSFINFO,
      ls_signer TYPE SSFINFO.


*****************************************************************************
* EJEMPLO DE FIRMA PKCS7
*****************************************************************************


*   Data to sign (can be text or binary)
l_data = 'Hola Amigo!'.  
APPEND l_data TO lt_data_to_sign.
l_data_len = 11.          " length


REFRESH lt_signers.
CLEAR ls_signer.

* Signer Certificate
ls_signer-id = 'CN=SR3, OU=I0610000083, OU=SAP Web AS, O=SAP Trust Community, C=DE'.
ls_signer-profile = 'SAPSYS.PSE'.  " Name of PSE file
APPEND ls_signer TO lt_signers.


CALL FUNCTION 'SSF_KRN_SIGN'
  EXPORTING
*   SSFTOOLKIT                         = ' '
*   STR_FORMAT                         = 'PKCS7'
   B_INC_CERTS                        = 'X'
*   B_DETACHED                         = ' '
*   B_INENC                            = 'X'
*   IO_SPEC                            = 'T'
    OSTR_INPUT_DATA_L                  = l_data_len
*   STR_HASHALG                        =
 IMPORTING
   OSTR_SIGNED_DATA_L                 = l_signed_data_len
   CRC                                = l_crc
  TABLES
    OSTR_INPUT_DATA                    = lt_data_to_sign
    SIGNER                             = lt_signers
    OSTR_SIGNED_DATA                   = lt_signed_data





          .
*   Escribir firma a fichero
CALL METHOD CL_GUI_FRONTEND_SERVICES=>GUI_DOWNLOAD
  EXPORTING
    BIN_FILESIZE              = l_signed_data_len
    FILENAME                  = 'C:\temp\datos_fima.p7b'
     FILETYPE                  = 'BIN'
*    IMPORTING
*      FILELENGTH                =
  CHANGING
    DATA_TAB                  = lt_signed_data
        .

Some interesting link: http://help.sap.com/saphelp_nw2004s/helpdata/en/4d/bf6f77a2c5446a86e0152f1b309db6/frameset.htm

I hope this help.

Best Regards,

Jorge Linares

0 Kudos

Hi Jorge!

First of all sorry for late feedback. AND: Thanx very much for your very informative reply!!!

My problem is that I have a ".cer" Certificate File knowing not much more about it than it is a file

From this file I have to "extract" the digital signature, base64-encode it and then send it along with an HTTP request.

Trying to open the cert file e.g. with Internet Explorer fails, because IE cannot read/interpret this file as a certificate file.

Any ideas how to proceed with this file? Can I just import it using TA STRUST? And if so can I then access it in my ABAP coding?

Sorry for stupid questions, but I am not the greatest fan of such Security stuff as well as I have a very, very low level of knowlegde/experience on it ....

Again thanx very much!

Regards,

Volker

0 Kudos

If Windows (NOT Internet Explorer) cannot open this file, it isn't a certificate. STRUST won't either. It is most likely something else (i.e. not a certificate).

BTW, it doesn't make much sense to extract the signature from something. It may be possible to help you, but you'll have to specify a whole lot more information.

0 Kudos

Hi!

As I have learned in the meantime the "cer" File is not a certificate but a keystore file containing a certificate. Like already mentioned and shown in Java it is possible to extract a certificate from a keystore file and use it for signing. Obviously this is not possible in ABAP, isn't it?

In parallel I will try to get the real certificate as a file ... But the question about ABAP above is still interesting ...

Regards,

Volker

0 Kudos

If the .cer file is actually a Java key store (they normally have the extension .jks), then you can use the java keytool command to convert the java keystore in a PKCS#12 file (containing all the certificates and keys). You can then use the sapgenpse tool (part of the SAP Cryptographic Library) to convert the PKCS#12 file into a .PSE file which you can then import using STRUST.

0 Kudos

Hi Jorge, I'm trying to Sign and Encrypt an output file, but I couldn't make it work. I followed all your tips, but I think that some things are missing. Actually I have an open thead:

[ |]

Could you please help me there? I have a few other question if you are available, and I will explain to you, exactly what i have done...

Regards,

Andrew83.

0 Kudos

Hello Jorge,

Please, help me with my problem:

I´m creating a XML file with the information of a billing with ABAP code, but I need to add the digital signature and I don´t know how I can get the tags: <ds:DigestValue>, <ds:SignatureValue .......>, <ds:X509Certificate>, <ds:Modulus>.

I have a file with extension P12. This file contains 2 keypairs.

I´ve executed the command: sapgenpse import_p12 -p certific.pse certific.pfx
I imported PSE file in STRUST transaction.

Do I need to execute additional steps???

When I executed the command sapgense, the result was that just one keypair was imported, Do I need to execute anything else???

What are the functions modules that I can use for getting tag values???

Thanks for all.

Former Member
0 Kudos

Hi,

I didn't understand your question first time. I thought you want to create digital signatures as the Java code you posted is doing so.

Let me see whether I know what do you mean...

A .cer file is a Base64 or binary encoded file which contains a single certificate, but it is not lika a Java Keystore. A Java Keystore is a collection of private keys, certificates, certificates of trusted CAs...

Do you want to extract the Digital Signature made by corresponding CA of this certificate?

for what? I don't see the use of this... Anyway, there are no standard way to do this in ABAP.

Are you trying to extract the private key to sign some data?? Then your file should be a PFX, PSE or other, but not a .CER file. Try to rename your file from .CER to .PFX and try to open it. Your Internet Explorer should launch the import wizard.

In SAP ABAP, files like JAVA Keystores are managed as PSE so you should have to convert your file to a PSE.

If you want to sign data in ABAP, see my first post.

Please, Let us know what is your purpose.

I hope this help.

Jorge

0 Kudos

Hi Sietze! Hi Jorge!

Thank you both for your very helpful tips so far.

And as you, Jorge, said indeed I'm trying to extract the private key to sign some data.

Now I'm still waiting to get the certificate from my colleagues. As soon as I have it and tried out your tips I will come back to this thread and inform you about the outcomings.

Again than you so far.

Regards,

Volker

0 Kudos

Hi!

Now I have exported the cert file from Java Keystore using keytool command keytool -export -keystore RsdCertStore.cer -file test.cer -alias Jeezes07

Then I got a readable certificate.

Then I successfully imported this certifictate into the System-PSE SAPSYS.pse using STRUST. Everything fine so far.

Wen I try to sign a string using the server's self-signed certificate everything is fine, but when I use the newly imported certificate, the function module SSF_KRN_SIGN returns the CRC code 5, meaning "problems with Signer ID"

Any ideas?

What did I do wrong? Maybe the command to export the certificate was not correct or complete enough?

Thanx for help!

Regards,

Volker

WolfgangJanzen
Product and Topic Expert
Product and Topic Expert
0 Kudos

According to your description you intend to sign data.

For that, you require not only the certificate but also the corresponding private key.

Starting from the Java keystore file you need to perform a PKCS#12 export which you then use to create an "ABAP keystore file" (PSE), using the command-line tool sapgenpse (option: import_p12). The resulting PSE file you can then upload to the ABAP system using transaction STRUST (PSE -> Import, PSE -> Save As).

It's advisable that you create your own "SSF Application" settings (using ABAP transaction SSFA) prior to uploading the PSE file. This allows you to specify a proper target in the "save as" operation mentioned above. Using a dedicated (application-specific) PSE file is recommended to avoid (configuration) conflicts with other applications. You should not use the "System PSE" (SAPSYS.pse), also the so-called "Default" application PSE should not be used - since both are "shared".

Regards, Wolfgang

0 Kudos

Hi,

Look at this link to convert a Java KeyStore to PKCS#12 (.PFX File)

[http://www.crionics.com/products/opensource/faq/signFree.htm#JKS2PFX|http://www.crionics.com/products/opensource/faq/signFree.htm#JKS2PFX]

Then you can convert the PFX to PSE with this command (In SAP Server):

sapgenpse import_p12 -p newPSE.pse source.pfx

In transaciont STRUST proceed as follows:

1) Create new SSF application parameters (Menu Environment -> SSF Parameters ) (SSF applications are mantained in table SSFAPLIC)

- Application DFAULT

- Security Product: SAPSECULIB

- SSF Format: PKCS#7

- Private Address book: newPSE.pse (Name of your PSE file!!)

- SSF Profile Name: newPSE.pse (Name of your PSE file!!)

- HAsh Alg.: SHA1

- See if other optional parameters apply in your case

2) Execute transaction STRUST and double-click on file icon in tree

- Select your generated PSE file in your local PC

- Select File -> Save As

- Choose option SSF and your application

Your PSE is generated under directory of SAP server: /usr/sap/<SID>/DVEBMGSii/sec (ii u2013 Instance Number)

Then you should have no problems in signing data.

Best Regards,

Jorge Linares

WolfgangJanzen
Product and Topic Expert
Product and Topic Expert
0 Kudos

>

> 1) Create new SSF application parameters (Menu Environment -> SSF Parameters ) (SSF applications are mantained in table SSFAPLIC)

> - Application DFAULT

Please choose a different one - not the "Default" application configuration.

0 Kudos

Hi Jorge! Hi Wolfgang!

Thank you very much so far for your tips. I will try this out and come back to you with the results.

Regards,

Volker

0 Kudos

Hi Jorge!

Extracting the public key using Java keytool works fine. But when trying to extract the private key from the keystore file I always get the Java exception java.security.UnrecoverableKeyException: Cannot recover key

The possible solution I have found in the web (password of keystore file must be the same as the password of key) obviously do not help, because the passwords are identical.

Any ideas what I can do now? Please remember: This keystore file currently is in productive use by the java program listed in my original post.

Thanx!

Regards,

Volker

Edited by: Volker Kolberg on May 18, 2009 11:18 AM

0 Kudos

Hey Volker!

Visit this link. There is Java code to export private key from JKS in base64 PEM format.

[http://www.anandsekar.com/2006/01/19/exporting-the-private-key-from-a-jks-keystore/|http://www.anandsekar.com/2006/01/19/exporting-the-private-key-from-a-jks-keystore/]

After that, you have to convert the exported data to PKCS12 (PFX) with openssl.

Example:

> openssl pkcs12 -export -in cert.pem -inkey key.pem -out cred.p12
Enter Export Password:
Verifying - Enter Export Password:
>
First, an explanation of the command line options: 

-export - generate a PKCS12 formatted file. 
-in cert.pem - read in the X509 PEM formatted certificate from the file cert.pem. 
-inkey key.pem - read in the X509 PEM formatted key from the file key.pem. 
-out cred.p12 - write out the PKCS12 formatted 'credential' to the file cred.p12.

I hope this help.

Best Regards

Edited by: Jorge Linares Miranda on May 28, 2009 4:44 PM

Former Member
0 Kudos

Hi Volker,

Here is a detailed example about converting Java Keystore in PKCS#12 format:

1) Generate keystore

keytool -genkey -keystore c:\temp\keys.jks -alias jorge -storepass 123456 -keypass 123456 -dname "CN=Jorge, OU=CSC, O=CSC

2) Export certificate in DER format

keytool -exportcert -keystore keys.jks -alias jorge -storepass 123456 -keypass 123456 -file cert.der

3) Export private key from keystore

a) Download ExportPrivateKey.zip from

http://www.anandsekar.com/wp-content/uploads/2006/01/ExportPrivateKey.zip

b) java -jar ExportPrivateKey.zip keys.jks JKS 123456 jorge key.pem

4) Download and extract openssl

5) convert certificate from DER to PEM

openssl x509 -inform DER -in cert.cer -outform PEM -out cert.pem

6) Concatenate text files cert.pem and key.pem in a new file keystore.pem with a text editor

7) Convert keystore in PEM format to PKCS12

openssl pkcs12 -export -in keystore.pem -out keystore.pfx

Other if useful: Convert only key from PEM to DER

openssl pkcs8 -inform PEM -nocrypt -in key.pem -outform DER -out key.der

Best regards,

Jorge

0 Kudos

Hi folks!

Thank you all very much. Problem was solved by creating a new certificate. Somehow this "mad" certificate store had some strange content.

Regards,

Volker