2011-08-12 11 views
6

Tengo problemas con algunos HMAC en Android. Estoy usando el algoritmo SHA1 con el siguiente código que aparece en toda la web cuando se busca Android hmac-sha1.Android HMAC-SHA1 Diferente al estándar Java HMAC-SHA1

 String base_string = "This is a test string"; 
     String key = "testKey"; 
     try { 
      Mac mac = Mac.getInstance("HmacSHA1"); 
      SecretKeySpec secret = new SecretKeySpec(key.getBytes("UTF-8"), mac.getAlgorithm()); 
      mac.init(secret); 
      byte[] digest = mac.doFinal(base_string.getBytes()); 

      String enc = new String(digest); 

      // Base 64 Encode the results 
      String retVal = Base64.encodeBase64String(enc.getBytes()); 
      Log.v(TAG, "String: " + base_string); 
      Log.v(TAG, "key: " + key); 
      Log.v(TAG, "result: " + retVal); 
     } catch (Exception e) { 
      System.out.println(e.getMessage()); 
     } 

Para probar este código he creado un sencillo programa estándar de Java con ella (en sustitución del Log.v telefónicas con llamadas System.out.println por supuesto) para que pueda comparar frente a la versión androide. En ambos casos, estoy usando los mismos valores de prueba para la cadena_base_ y la clave.

Además he verificado los resultados codificados del Java estándar con algunas funciones de PHP y un servidor de validación (usando algunos tokens de OAuth). El código funciona bien en el programa Java estándar, pero no funciona en el programa Android. He hecho muchas búsquedas y no puedo descifrar qué está mal. ¿Alguien alguna vez experimentó esto?

Estos son los resultados de Java y Android estándar ...

  • Java (y PHP): fH/+pz0J5XcPZH/d608zGSn7FKA=
  • Programa de Android: fH/vv73vv709Ce+/vXcPZH/vv73vv71PMxkp77+9FO+/vQ==

buscando en él un poco más Soy seguro que es la función de hmac y no la codificación de Base64 donde se equivoca al comparar los valores de hmac, la versión de Android tiene todo tipo de espacios extra y otros símbolos de caracteres desconocidos en comparación con el programa de Java.

¡Se agradece cualquier ayuda!

+1

No se puede encontrar el método 'android.util.Base64.encodeBase64String (...)' –

Respuesta

13

Supongo que se trata de un problema de codificación de cadena.

¿Qué estás haciendo aquí?

 String enc = new String(digest); 

     // Base 64 Encode the results 
     String retVal = Base64.encodeBase64String(enc.getBytes()); 

Que a su vez los bytes en una cadena, y luego de vuelta a una matriz de bytes de nuevo (que luego se base 64 codificar).

su lugar, haga lo siguiente:

 String retVal = Base64.encodeBase64String(digest); 

En general, nunca jamás usuario String.getBytes() o new String(byte[]) si quieres un programa portátil. Y nunca intente convertir una matriz de bytes arbitraria (que antes no era una cadena) en una cadena (que no sea algo como Base64).

+0

¡Guau! ¡Tan sencillo! Sabía que iba a ser algo así, pero realmente estaba rascándome la cabeza. ¡Gracias! Eso solucionó el problema de inmediato. – nlbers

+0

+1 para una gran respuesta :) –

+1

¿Dónde se encuentra el método encodeBase64String()? No lo encuentro en ningún lado. – Gabrielle

Cuestiones relacionadas