SHA256 Los resultados de Hash resultan diferentes en Android y iOS para números grandes

Estoy tratando de Hash un BigInteger / BigNum y estoy obteniendo diferentes resultados en Android / iOS. Necesito obtener el mismo resultado de Hash para que ambas aplicaciones funcionen según el protocolo SRP. En una inspección más cercana está funcionando bien para los números positivos, pero no funciona para los números negativos (primer nibble mayor de 7). No estoy seguro de cuál es correcto y cuál debe ser ajustado para que coincida con el otro.

Androide:

void hashBigInteger(String s) { try { BigInteger a = new BigInteger(s, 16); MessageDigest sha = MessageDigest.getInstance("SHA-256"); byte[] b = a.toByteArray(); sha.update(b, 0, b.length); byte[] digest = sha.digest(); BigInteger d = new BigInteger(digest); Log.d("HASH", "H = " + d.toString(16)); } catch (NoSuchAlgorithmException e) { throw new UnsupportedOperationException(e); } } 

IOS:

 void hashBigNum(unsigned char *c) { BIGNUM *n = BN_new(); BN_hex2bn(&n, c); unsigned char buff[ SHA256_DIGEST_LENGTH ]; int len = BN_num_bytes(n); unsigned char * bin = (unsigned char *) malloc( len ); BN_bn2bin(n, bin); hash( SRP_SHA256, bin, len, buff ); fprintf(stderr, "H: "); for (int z = 0; z < SHA256_DIGEST_LENGTH; z++) fprintf(stderr, "%2x", buff[z]); fprintf(stderr, "\n"); free(bin); } 

Resultados:

 Source String = "6F" Android Hash = 65c74c15a686187bb6bbf9958f494fc6b80068034a659a9ad44991b08c58f2d2 iOS Hash = 65c74c15a686187bb6bbf9958f494fc6b80068034a659a9ad44991b08c58f2d2 Source String = "FF" Android Hash = 06eb7d6a69ee19e5fbdf749018d3d2abfa04bcbd1365db312eb86dc7169389b8 iOS Hash = a8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89 

El problema está en el código JAVA. new BigInteger(s, 16).toByteArray() no es seguro para ceros a la izquierda. Ver comentario de póster en Convertir una representación de cadena de un volcado hexadecimal en una matriz de bytes usando Java?

La representación de bits de FF con Android es 00000000 11111111 mientras que en iOS es 11111111 . Los ceros principales son la razón porque el hash SHA256 es diferente.

Simplemente cambie el convertidor Hex a byte utilizando un método de la publicación enlazada para obtener la misma matriz de bytes (sin ceros). Por ejemplo

 public static byte[] hexStringToByteArray(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16)); } return data; } void hashBigInteger(String s){ try{ MessageDigest sha = MessageDigest.getInstance("SHA-256"); byte b[] = hexStringToByteArray(s); sha.update(b,0,b.length); byte digest[] = sha.digest(); BigInteger d = new BigInteger(1,digest); System.out.println("H "+d.toString(16)); }catch (NoSuchAlgorithmException e){ throw new UnsupportedOperationException(e); } } 

Para la correcta impresión HEX, cambie también BigInteger d = new BigInteger(digest); con

 BigInteger d = new BigInteger(1,digest); 

Una forma es convertir sus números grandes en cadenas y obtener hash de ellos.

  • Peer to peer android and iOS con Wifi directo (conectividad multipista?)
  • Unity c #, tomar captura de pantalla y guardar en archivo como jpg
  • Xamarin Form Master Página de detalles que no se muestra
  • ¿Podemos invocar la funcionalidad de compartir nativo del teléfono inteligente con jquery?
  • Cómo cambiar el nombre de visualización de una aplicación en reactivo-nativo
  • Android equivalente de NSUserDefaults en iOS
  • Cómo obtener MarkerId en Artoolkitplus en android
  • Cómo trabajar con diferentes resoluciones de pantalla
  • Configuración del visor para escalar para ajustar tanto el ancho como la altura
  • Intercambiar píxeles de MainTex con otras texturas a través de la superficie Shader (Unity)
  • Portales de aplicaciones móviles centralizados y descentralizados
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.