2010-01-07 3 views
13

Ich arbeite an der Implementierung von Bing Cashback. Um eine eingehende Anfrage von Bing als gültig zu verifizieren, stellen sie eine Signatur zur Verfügung. Die Signatur ist ein 160-Bit-SHA-1-Hash der URL, der mit RSA verschlüsselt wurde.Erstellen von RSA-Schlüsseln aus bekannten Parametern in Java

Microsoft bietet den RSA "öffentlichen Schlüssel", Modul und Exponent, mit dem ich den Hash entschlüsseln soll.

Gibt es eine Möglichkeit, die Java-Schlüsselobjekte zu erstellen, die zum Entschlüsseln des Hash benötigt werden, wie Microsoft sagt?

Alles, was ich finden kann, erstellt RSA-Schlüsselpaare automatisch, da RSA so funktionieren soll. Ich würde wirklich gerne die Java-Objekte verwenden, wenn das überhaupt möglich ist, da das natürlich zuverlässiger ist als eine handcodierte Lösung.

Der von Ihnen bereitgestellte Beispielcode befindet sich in .NET und verwendet eine .NET-Bibliotheksfunktion, um den Hash zu überprüfen. Insbesondere RSACryptoServiceProvider.VerifyHash()

Antwort

20
RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent); 
KeyFactory factory = KeyFactory.getInstance("RSA"); 
PublicKey pub = factory.generatePublic(spec); 
Signature verifier = Signature.getInstance("SHA1withRSA"); 
verifier.initVerify(pub); 
verifier.update(url.getBytes("UTF-8")); // Or whatever interface specifies. 
boolean okay = verifier.verify(signature); 
+0

Wird Cipher einen öffentlichen Schlüssel in DECRYPT_MODE nehmen? – meleager

+0

Ja, die RSA-Verschlüsselung der meisten Provider akzeptiert einen öffentlichen Schlüssel für die Entschlüsselung. Sie werden sogar nach der richtigen Polsterung suchen. Es ist jedoch besser, eine "Signatur" -Instanz zu verwenden. Ich werde meine Antwort aktualisieren, um zu demonstrieren. – erickson

0

So etwas sollte es tun:

private PublicKey convertPublicKey(String publicKey) throws Exception{ 
    PublicKey pub = null; 

    byte[] pubKey = Hex.decodeHex(publicKey.toCharArray()); 
    X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubKey); 
    KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
    pub = (RSAPublicKey) keyFactory.generatePublic(pubSpec); 

    return pub; 
    } 

Dies setzt voraus, der öffentliche Schlüssel wird als Hex-String angegeben, und Sie werden die Apache Commons Codec library

Wenn Sie brauchen Haben Sie den Schlüssel in einem anderen Format, versuchen Sie die KeyFactory für weitere Informationen.

+0

Ich muss überprüfen und sehen, ob wir diese Bibliothek haben oder ob wir es bekommen können. Zusätzlich wird das Cipher-Objekt einen öffentlichen Schlüssel in DECRYPT_MODE nehmen? Das scheint mir sehr rückständig zu sein. – meleager

+0

Es wird verwendet, wenn Sie die Sun JRE, aber nicht die IBM Version verwenden. Zufälligerweise wird auch eine IBM JRE, die den Krypto-Provider des Bouncy Castle nutzt, funktionieren. –

+0

Danke, ich werde es versuchen. – meleager

2

Verwenden Sie java.security.spec.RSAPublicKeySpec. Er kann einen Schlüssel aus Exponent und Modul konstruieren. Verwenden Sie anschließend java.security.KeyFactory.generatePublic() mit der Schlüsselspezifikation als Parameter.