Ich schreibe einen Client in Python2 mit der Python-Crypto-API, um eine XML-Datei digital zu signieren, und ich habe einen Dienst in Scala geschrieben, der die Signatur überprüfen soll. Mein Python-Code sieht wie folgt aus:Problem interpolieren RSA-Signaturen zwischen Python und Java/Scala
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA
from os import urandom
import logging
...
...
die Schlüssel zu generieren (keysize 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)
Und in den Schlüssel zu lesen:
self.__private_key = fpri.read()
self.__public_key = fpub.read()
self.__key = RSA.importKey(self.__private_key)
Und digital zu signieren
logging.debug('Data to sign: "%s"' % data)
digest = SHA.new(data.strip()).digest()
return str(self.__key.sign(digest, None)[0])
Dann in Sc ala/Java, verwende ich die folgenden:
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())
}
}
Ich verwandle die PEM Öffentlichkeit durch die Kunden in einen binären öffentlichen Schlüssel erzeugen Schlüssel, damit es von Java gelesen werden:
openssl rsa -in src/com/example/security/key.pub -inform PEM -out src/com/example/security/key.der -outform DER -pubin
In den Bereichen Verkehr, Ich unterscheide XML und Signatur mit doppelten neuen Zeilen. Ich weiß, nachfolgende Leerzeichen Probleme verursachen kann, so ich diese Streifen hinzugefügt/trimmt oben und überprüfe ich die Protokolle und überprüfen, ob die Daten identisch:
Python Auftraggeber:
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>"
Aber innerhalb des Scala-Dienstes gibt es false zurück, wenn ich versuche, die Signatur zu überprüfen. Ich denke irgendwo gebe ich nicht den richtigen Signatur-/Schlüsseltyp an, aber ich bin mir nicht sicher wo.
Können Sie zuerst sicherstellen, dass der signierte String und der verifizierte String * genau * gleich sind? Sie können zum Beispiel die SHA von ihnen überprüfen. Es könnte möglich sein, dass die Codierung einige Zeichen geändert hat. – Jus12
Ein paar Gedanken ... (Übrigens, ich habe noch nie Python benutzt). (1) Ist die SHA-Methode von Python wie die SHA1-Methode in Scala? Siehe [dies] (http://www.rsa.com/rsalabs/node.asp?id=2252). (2) Überprüfen Sie, ob die Python-Methode SHA1 intern berechnet. Versuchen Sie, 'data.strip()' an die 'sign'-Methode anstelle des Digests zu übergeben. – Jus12