2010-01-07 13 views
13

Estoy trabajando para implementar Bing Cashback. Para verificar que una solicitud entrante de Bing es válida, proporcionan una firma. La firma es un hash SHA-1 de 160 bit de la url encriptado usando RSA.Creación de claves RSA a partir de parámetros conocidos en Java

Microsoft proporciona la RSA "clave pública", módulo y exponente, con la que se supone que debo descifrar el hash.

¿Hay alguna forma de crear los objetos clave de Java necesarios para descifrar el hash como dice Microsoft?

Todo lo que puedo encontrar crea automáticamente pares de claves RSA, ya que así es como se supone que RSA funciona. Realmente me gustaría utilizar los objetos Java si es posible, ya que obviamente es más confiable que una solución codificada a mano.

El código de ejemplo que han proporcionado está en .NET y utiliza una función de biblioteca .NET para verificar el hash. Específicamente RSACryptoServiceProvider.VerifyHash()

Respuesta

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

Will Cipher tomará una clave pública en DECRYPT_MODE? – meleager

+0

Sí, la implementación de cifrado RSA de la mayoría de los proveedores aceptará una clave pública para el descifrado. Incluso verificará el relleno correcto. Sin embargo, es mejor usar una instancia de 'Firma'. Actualizaré mi respuesta para demostrar. – erickson

0

Algo como esto debe hacer el truco:

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; 
    } 

Esto supone que la clave pública se da como una cadena hexadecimal, y necesitará la Apache Commons Codec library

Si tener la clave en un formato diferente, pruebe el KeyFactory para obtener más información.

+0

Tendré que verificar y ver si tenemos esa biblioteca o si podemos conseguirla. Además, ¿el objeto Cipher tomará una clave pública en DECRYPT_MODE? Esto me parece muy retrógrado. – meleager

+0

Lo hará si está utilizando Sun JRE, pero no la versión de IBM. Casualmente, el IBM JRE que utiliza el proveedor de criptografía Bouncy Castle también funcionará. –

+0

Gracias, lo intentaré. – meleager

2

Use java.security.spec.RSAPublicKeySpec. Puede construir una clave a partir de exponente y módulo. Luego use java.security.KeyFactory.generatePublic() con la especificación de clave como parámetro.

Cuestiones relacionadas