Topic
  • 8 replies
  • Latest Post - ‏2016-09-26T20:41:47Z by Pablo_Sanchez
SystemAdmin
SystemAdmin
6772 Posts

Pinned topic Trying to decrypt in datapower using RSA private key

‏2012-11-09T16:22:47Z |
Hi,

I am new to DataPower and to make matters worse I am also new to XSL, XSLT and XPATH. My objective is to encrypt a string in java, send it to DataPower
along with other information in an HTTP "GET" request, decrypt it and compare it to one of the parameters in the request using an RSA public/private
key pair. If the information matches then route the request to a backend URL, and if it doesn't match do no more processing.

I have generated the RSA keys in DP and have been able to encrypt the string in java using the public key and send the request to DP.

I have configured a Multi-Protocol Gateway on Dp with a policy that has 4 actions:

1) Match action, which matches any HTTP GET.

2) Convert query params to XML action.
The input to this action is(I shortened the iebToken considerably for brevity):
/?iebToken=Yr1vNMPw0Cn%2BQaMg&machine_serial=1234567&machine_type=ABCD&machine_signature=EFGH&authorization_code=gsgtt&callback=dojo.io.script.jsonp_dojoIoScript2._jsonpCallback

The output from the action is:
<request>

<url>/?iebToken=Yr1vNMPw0Cn%2BQaMg&machine_serial=1234567&machine_type=ABCD&machine_signature=EFGH&authorization_code=gsgtt&callback=dojo.io.script.jsonp_dojoIoScript2._jsonpCallback</url>
<base-url>/</base-url>
<args src="url">
<arg name="iebToken">Yr1vNMPw0Cn+QaMg</arg>
<arg name="machine_serial">1234567</arg>
<arg name="machine_type">ABCD</arg>
<arg name="machine_signature">EFGH</arg>
<arg name="authorization_code">gsgtt</arg>
<arg name="callback">dojo.io.script.jsonp_dojoIoScript2._jsonpCallback</arg>
</args>

</request>

3) Decrypt action. I attempted to decrypt the "iebToken" here using the private key generated earlier.
In the Configure Decrypt Action "Basic" tab I selected the "Selected Elements (Field-Level)" radio button.
In Configure Document Crypto Map I have XPath Expression: //*

This is where I need some help. Nothing happens here at all as far as I can tell. I enabled the probe and looked at the output from this step and it's the same as the
input. It could also be working and as a DP novice I don't know how to tell if it is or isn't.

4) Results action - no modificaton

Can anyone help me with this?
Updated on 2012-11-16T16:45:20Z at 2012-11-16T16:45:20Z by inestlerode
  • HermannSW
    HermannSW
    6388 Posts

    Re: Trying to decrypt in datapower using RSA private key

    ‏2012-11-12T18:20:43Z  
    > and have been able to encrypt the string in java using the public key and send the request to DP.
    >
    Can you please attach the Java code you used?

     
    Hermann<myXsltBlog/> <myXsltTweets/>
  • SystemAdmin
    SystemAdmin
    6772 Posts

    Re: Trying to decrypt in datapower using RSA private key

    ‏2012-11-12T19:31:22Z  
    • HermannSW
    • ‏2012-11-12T18:20:43Z
    > and have been able to encrypt the string in java using the public key and send the request to DP.
    >
    Can you please attach the Java code you used?

     
    Hermann<myXsltBlog/> <myXsltTweets/>
    Here is the java:

    // encrypt the token
    byte[] encryptedToken = new byte[0];
    BASE64Encoder b64Encoder = new BASE64Encoder();
    try {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(token);
    // Close the streams
    oos.close();
    baos.close();
    encryptedToken = encryptToken(baos.toByteArray());
    } catch (IOException e) {
    logwriter.logException(LogLevel.ERROR, e);
    }
    return b64Encoder.encode(encryptedToken);

    private static byte] encryptToken(byte[ data) throws IOException {
    try {
    PublicKey pubKey = getPublicKey("/temp/" + PUBLIC_KEYFILE);
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, pubKey);
    byte[] cipherData = cipher.doFinal(data);
    return cipherData;
    } catch (Exception e) {
    throw new RuntimeException("Error encrypting token", e);
    }
    }

    private static PublicKey getPublicKey(String filename)
    throws IOException {
    File f = new File(filename);
    FileInputStream fis = new FileInputStream(f);
    DataInputStream dis = new DataInputStream(fis);
    try {
    CertificateFactory d = CertificateFactory.getInstance("X.509");
    X509Certificate x509 = (X509Certificate)d.generateCertificate(dis);
    PublicKey pubKey = x509.getPublicKey();

    return pubKey;
    } catch (Exception e) {
    throw new RuntimeException("Error getting public key", e);
    } finally {
    dis.close();
    }
    }
  • SystemAdmin
    SystemAdmin
    6772 Posts

    Re: Trying to decrypt in datapower using RSA private key

    ‏2012-11-13T04:52:18Z  
    I recall attempting something like this some years back and was told that I shouldn't be using asymmetric encryption directly. Rather, symmetric encryption should be used and, if necessary, asymmetric encryption can be used to transmit the symmetric key. The reason is because asymmetric encryption only works well on small input sizes. The DP public APIs support this method.
  • SystemAdmin
    SystemAdmin
    6772 Posts

    Re: Trying to decrypt in datapower using RSA private key

    ‏2012-11-14T13:47:13Z  
    I recall attempting something like this some years back and was told that I shouldn't be using asymmetric encryption directly. Rather, symmetric encryption should be used and, if necessary, asymmetric encryption can be used to transmit the symmetric key. The reason is because asymmetric encryption only works well on small input sizes. The DP public APIs support this method.
    Actually, the data we are encrypting is quite small, probably smaller than the key itself. I am looking to see if what I have done on the DataPower side is correct or not. It seems like the decrypt step should have done something. I was hoping someone out there has done something similar and can give me an idea of where I went wrong.
  • inestlerode
    inestlerode
    166 Posts

    Re: Trying to decrypt in datapower using RSA private key

    ‏2012-11-16T16:45:20Z  
    Actually, the data we are encrypting is quite small, probably smaller than the key itself. I am looking to see if what I have done on the DataPower side is correct or not. It seems like the decrypt step should have done something. I was hoping someone out there has done something similar and can give me an idea of where I went wrong.
    Regardless of whether your data is small or not it is never a good idea to use RSA encryption directly on the data payload. No protocol out there does this and for good reason. By doing this you are almost definitely creating a ciphertext validity oracle that will make you vulnerable to various cryptographic attacks such as this one:
    http://www.springerlink.com/content/j5758n240017h867/

    Real protocols use a random symmetric key (3DES or AES) to encrypt the payload and then they use RSA to encrypt that random symmetric key. This is the more secure way to do something like this. Once you move to such a system you will discover why there are existing standards in this area to be used. There are issues of how to encode the two pieces and how to process them securely on the receiving end (without creating the oracle that leads to the above attack).

    We have already dealt with all of these issues in the standard decrypt and cryptobin actions. I would suggest using standards compliant XML Encryption or PKCS#7 for this so that you can use the decrypt action or cryptobin decrypt action respectively rather than trying to reinvent the wheel (introducing security vulnerabilities in the process).
  • GeetPandey
    GeetPandey
    38 Posts

    Re: Trying to decrypt in datapower using RSA private key

    ‏2016-09-22T00:39:55Z  
    Actually, the data we are encrypting is quite small, probably smaller than the key itself. I am looking to see if what I have done on the DataPower side is correct or not. It seems like the decrypt step should have done something. I was hoping someone out there has done something similar and can give me an idea of where I went wrong.

    Were you able to find solution to this?

  • ThomasVS
    ThomasVS
    127 Posts

    Re: Trying to decrypt in datapower using RSA private key

    ‏2016-09-26T12:31:59Z  

    To my knowledge, there is no DataPower functionality to encrypt/decrypt strings using asymmetric keys.

  • Pablo_Sanchez
    Pablo_Sanchez
    105 Posts

    Re: Trying to decrypt in datapower using RSA private key

    ‏2016-09-26T20:41:47Z  
    • ThomasVS
    • ‏2016-09-26T12:31:59Z

    To my knowledge, there is no DataPower functionality to encrypt/decrypt strings using asymmetric keys.

    We do it here... String encryption using asymmetric keys. After struggling a bit with it, the "correct" way of doing it is a little bit tricky... Basically you encrypt the string with a symmetric key (session-key) and since the client needs it to decrypt, you need to encrypt the symmetric key (session-key) with the recipient certificate (asymmetric). To encrypt using asymmetric key (cert/key) is not recommended from a security perspective.

    Below is the PoC XSLT I did when I started researching this:

     

    <?xml version="1.0" encoding="UTF-8" ?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions" xmlns:dpconfig="http://www.datapower.com/param/config" extension-element-prefixes="dp"
        exclude-result-prefixes="dp dpconfig">
        <xsl:template match="/">

            <!-- Setting the algorithm -->
            <xsl:variable name="vAlgorithm">
                <xsl:value-of select="'http://www.w3.org/2001/04/xmlenc#aes256-cbc'" />
            </xsl:variable>
            <!-- Generating the SessionKey -->
            <xsl:variable name="vSessionKey">
                <xsl:value-of select="dp:generate-key($vAlgorithm)" />
            </xsl:variable>
            <!-- Generating the Recipient Key - we set the Recipient Certificate at this point -->
            <xsl:variable name="vRecipientKey">
                <xsl:value-of select="dp:encrypt-key($vSessionKey, 'name:CERT_Encrypt', 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p')" />
            </xsl:variable>
            <!-- This is the Data we'll encrypt -->
            <xsl:variable name="vData" select="'String to be encrypted'"/>
            <!-- Encrypting the data -->
            <xsl:variable name="vCipherText">            
                <xsl:value-of select="dp:encrypt-string('http://www.w3.org/2001/04/xmlenc#aes256-cbc',$vSessionKey,$vData)" />
            </xsl:variable>        
            <!-- THE STEPS ABOVE ARE FOR SIMULATING THE "Client"
                CREATING KEYS AND ENCRYPTING DATA
             -->
            
            
            <!-- THE STEPS BELOW ARE FOR SIMULATING THE "Server"
                DECRYPTING THE KEYS TO GET SESSION KEY AND FINALLY DECRYPTING THE DATA TO GET THE RAW FORM OF IT
             -->
            <!-- Decrypting the Session Key - which was encrypted with the public key (certificate) to be shared/sent across -->
            <xsl:variable name="vDecryptedKey">
                <xsl:value-of select="dp:decrypt-key($vRecipientKey, 'name:KEY_Encrypt', 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p')" />
            </xsl:variable>
            <!-- Decrypting the data using the Session Key retrieved from previous step -->
            <xsl:variable name="vClearData">
                <xsl:value-of select="dp:decrypt-data('http://www.w3.org/2001/04/xmlenc#aes256-cbc', $vDecryptedKey, $vCipherText)" />
            </xsl:variable>

            <out>
                <SessionKey>
                    <xsl:value-of select="$vSessionKey" />
                </SessionKey>
                <RecipientKey>
                    <xsl:value-of select="$vRecipientKey" />
                </RecipientKey>
                <EncryptedData>
                    <xsl:value-of select="$vCipherText" />
                </EncryptedData>
                <DecryptedRecipientKey>
                    <xsl:value-of select="$vDecryptedKey" />
                </DecryptedRecipientKey>
                <DecryptedData>
                    <xsl:value-of select="$vClearData" />
                </DecryptedData>
            </out>

        </xsl:template>
    </xsl:stylesheet>

    Updated on 2016-09-26T20:44:57Z at 2016-09-26T20:44:57Z by Pablo_Sanchez