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:

  • Disposition relative Android avec largeur de bouton en utilisant le poids
  • Icône de miniature de la boîte grise console du développeur Google Play
  • Android Studio: Comment modifier le style et le comportement par défaut du curseur?
  • Activité d'héritage avec AndroidAnnotations
  • Android - Comment fermer une activité sur le clic de bouton?
  • Comment faire un écran de démarrage (écran visible lorsque l'application démarre)?
  • 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 AES dans iOS et Android, et décryptage dans C # .NET
  • Cryptage des données sur Android, AES-GCM ou AES ordinaire?
  • 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.