Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble interpolating RSA signatures between Python and Java/Scala

I'm writing a client in Python2 with the python-crypto API to digitally sign an XML file and I have a service written in Scala that is suppose to verify the signature. My Python code looks something like this:

from Crypto.PublicKey import RSA
from Crypto.Hash import SHA
from os import urandom
import logging

...
...

To generate the keys (keysize is 2048):

self.__key = RSA.generate(self.keySize,urandom)
self.__private_key = self.__key.exportKey()
self.__public_key = self.__key.publickey().exportKey()
with open(pubPath,'w') as fpub:
    logging.info("Writing Public Key to %s" % pubPath)
    fpub.write(self.__public_key)
with open(priPath,'w') as fpri:
    logging.info("Writing Private Key to %s" % priPath)
    fpri.write(self.__private_key)

And for reading in the keys:

self.__private_key = fpri.read()
self.__public_key = fpub.read()
self.__key = RSA.importKey(self.__private_key)

And to digitally sign

logging.debug('Data to sign: "%s"' % data)
digest = SHA.new(data.strip()).digest()
return str(self.__key.sign(digest, None)[0])

Then in Scala/Java, I use the following:

package com.example.security
import com.example.action.ActionRequest
import java.io.BufferedInputStream
import java.security.spec.X509EncodedKeySpec
import java.security.KeyFactory
import java.security.PublicKey
import java.security.Signature
import org.apache.log4j.Logger

class SignatureSecurityManageer extends SecurityManagerTrait {

    def loadPublicKey() : PublicKey = {
        val stream : BufferedInputStream = new BufferedInputStream(this.getClass().getResourceAsStream("/com/example/security/key.der"))
        var key = new Array[Byte](stream.available())
        stream.read(key)
        KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(key))
    }

    def securityFilter(req : ActionRequest) : Boolean = {

        var parts = req.data.split("\n\n")

        var log : Logger = Logger.getLogger(this.getClass());
        log.trace("Data \"%s\"".format(parts(0)))
        log.trace("Sig \"%s\"".format(parts(1)))

         var sg = Signature.getInstance("SHA1withRSA");
         sg.initVerify(loadPublicKey())
         sg.update(parts(0).trim().getBytes())
         sg.verify(parts(1).trim().getBytes())
    }
}

I transform the PEM public key generated by the client into a binary public key so it can be read by Java:

openssl rsa -in src/com/example/security/key.pub -inform PEM -out src/com/example/security/key.der -outform DER -pubin

In the transport, I separate the XML and the signature with double new lines. I realize trailing whitespace can present problems so I added those strip/trims above and I check the logs and verify that the data is identical:

Python Client:

2012-04-09 14:24:51,089: Data to sign: "<?xml version="1.0" ?><AgraData><package id="Local-Laptop" timestamp="1333945491074"><sensors><sensor id="SUMTEMP001" type="Temperature" units="C"><data>8</data></sensor><sensor id="SUMVOL001" type="Volume" units="l"><data>27</data></sensor><sensor id="SUMFLO001" type="FlowRate" units="l"><data>41.142</data></sensor></sensors></package></AgraData>"

Scala Service:

[2012-04-09 14:24:51,771] com.urbanalta.agrastore.security.SignatureSecurityManageer TRACE - Data "<?xml version="1.0" ?><AgraData><package id="Local-Laptop" timestamp="1333945491074"><sensors><sensor id="SUMTEMP001" type="Temperature" units="C"><data>8</data></sensor><sensor id="SUMVOL001" type="Volume" units="l"><data>27</data></sensor><sensor id="SUMFLO001" type="FlowRate" units="l"><data>41.142</data></sensor></sensors></package></AgraData>"

But within the Scala service, it returns false when I try to verify the signature. I think somewhere I'm not specifying the right signature/key type, but I'm not sure where.

like image 576
djsumdog Avatar asked Nov 14 '22 07:11

djsumdog


1 Answers

This might be another instance of this submission where it's not just the digest but the AlgorithmIdentifier and the digest that are signed.

like image 107
Phil Cooper Avatar answered Nov 16 '22 02:11

Phil Cooper