Le cryptage AES fait des résultats différents dans iOS et Android

En essayant de chiffrer les données d'échantillons à l'aide de l'algorithme AES128 avec CBC et PKCS7 padding dans Android et iOS, mais les résultats sont différents 🙁

Code Android:

  • Liste de défilement Affichage en douceur et par programme
  • Comment cacher un bouton par programme?
  • Javascript: des solutions de rechange pour obtenir Chrome pour Android pour désactiver les écouteurs touchmove et touchend event autres que l'utilisation de event.preventDefault ()?
  • WebView loadDataWithBaseUrl - problème étrange dans Android 4.0.3
  • GCM FC / Sender id n'est pas défini sur le constructeur
  • Comment exécuter une tâche Async à plusieurs reprises après des intervalles de temps fixes
  • private static final byte[] KEY = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10}; int srcBuffSiz = 1024; byte[] srcBuff = new byte[srcBuffSiz]; Arrays.fill(srcBuff, (byte)0x01); SecretKeySpec skeySpec = new SecretKeySpec(KEY, "AES"); Cipher ecipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); ecipher.init(Cipher.ENCRYPT_MODE, skeySpec); byte[] dstBuff = ecipher.doFinal(srcBuff); int bytesEncrypted = dstBuff.length; 

    Code iOS:

      // Source buffer size_t srcBuffSiz = 1024; unsigned char* srcBuff = new unsigned char[srcBuffSiz]; memset(srcBuff, 0x01, srcBuffSiz); // Destination buffer size_t dstBuffSiz = srcBuffSiz + 128; unsigned char* dstBuff = new unsigned char[dstBuffSiz]; memset(dstBuff, 0x00, dstBuffSiz); unsigned char keyPtr[kCCKeySizeAES128] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10}; size_t bytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCKeySizeAES128, NULL /* initialization vector (optional) */, srcBuff, srcBuffSiz, /* input */ dstBuff, dstBuffSiz, /* output */ &bytesEncrypted); 

    Donc, dans les deux cas, j'essaie de crypter un tampon de 1024 octets par exemple (préalablement rempli de valeurs 0x01) en utilisant une clé d'échantillon prédéfinie.

    Premier et dernier 6 octets de tampon crypté dans iOS:

     ED CC 64 27 A8 99 ... 0C 44 9F EC 34 FC 

    Premier et dernier 6 octets de tampon crypté dans Android:

     AE 65 A9 F7 7F 0E ... 1F BD AE 8B 85 ED 

    Une idée?

    Si je supprime Cipher.getInstance ("AES / CBC / PKCS7Padding") à Cipher.getInstance ("AES"), alors les premiers multiplets de tampon crypté seront les mêmes, mais à partir du 17ème octet …

    IOS:

     ED CC 64 27 A8 99 DA 83 D5 4A B0 03 0F E7 DD A7 35 F2 50 5C 49 47 CC 3B 2F AB D1 61 05 

    Android:

     ED CC 64 27 A8 99 DA 83 D5 4A B0 03 0F E7 DD A7 ED CC 64 27 A8 99 DA 83 D5 4A B0 03 0F 

  • Cryptage des données sur Android, AES-GCM ou AES ordinaire?
  • Cryptage AES dans iOS et Android, et décryptage dans C # .NET
  • Android 4.2 a enfreint mon code de cryptage / décryptage AES
  • 2 Solutions collect form web for “Le cryptage AES fait des résultats différents dans iOS et Android”

    Je rappelle vaguement que j'avais une fois un problème similaire de «synchronisation» du cryptage entre Android et iPhone, et la solution était dans l'utilisation appropriée de l'IV (vecteur d'initialisation). Donc, probablement, la mise en marche d'une utilisation IV explicite dans Android pourrait aider:

     final byte[] iv = new byte[16]; Arrays.fill(iv, (byte) 0x00); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); .. // the rest of preparations ecipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec); 

    Parce que lorsque sur iPhone vous passez NULL comme IV, il peut être utilisé en interne par défaut pour le juste indiqué ci-dessus.

    Mais dans l'environnement de production, vous devez utiliser un vecteur d'initialisation (cryptographiquement sécurisé pseudo-) aléatoire, stocké avec les données. Ensuite, il est sûr pour tous les modes d'opérations. [1]

    Le code Android utilise explicitement le mode CBC. Mais le code iOS ne le spécifie pas. Au moins, je ne le vois pas là-bas.

    De plus, lorsque vous utilisez le mode CBC, vous devez également spécifier Vector d'initialisation:

     byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; // use different random value AlgorithmParameterSpec algorithmSpec = new IvParameterSpec(iv); Cipher ecipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); ecipher.init(Cipher.ENCRYPT_MODE, skeySpec, algorithmSpec); 

    Vous devez utiliser le même vecteur d'initialisation sur iOS et spécifiez également que vous utilisez le mode CBC.

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.