AES-Verschlüsselung Android <-> iOS unterschiedliche Ergebnisse bei Nachrichtenlänge> 15 Byte

Ich habe ein echtes Problem beim Verstehen der Verschlüsselung / Verschlüsselung auf beiden Geräten.

1. Wenn wir eine Nachricht unter iOS und Android mit Cipher AES verschlüsseln und die Länge der Zeichenfolge nicht größer als 16 ist (z. B. "abcdefghijklmno"), erhalten wir das gleiche Ergebnis, nachdem wir sie mit demselben Schlüssel / Passwort verschlüsselt haben.

2. Wenn Sie jedoch eine längere Nachricht senden, erhalten Sie unter iOS und Android unterschiedliche Ergebnisse (z. B. "abcdefghijklmnop").

Ich habe ziemlich viel nachgeforscht, wie man die gleichen Parameter für beide Geräte erhält, und zuerst dachte ich, dass es sicher ist.

Hier ist mein Chiffriercode zum Verschlüsseln:

public String encode(Context context, String password, String text)
        throws NoPassGivenException, NoTextGivenException {
    if (password.length() == 0 || password == null) {
        throw new NoPassGivenException("Please give Password");
    }

    if (text.length() == 0 || text == null) {
        throw new NoTextGivenException("Please give text");
    }

    try {
        SecretKeySpec skeySpec = getKey(password);
        byte[] clearText = text.getBytes("UTF8");


        //IMPORTANT TO GET SAME RESULTS ON iOS and ANDROID
        final byte[] iv = new byte[16];
        Arrays.fill(iv, (byte) 0x00);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

        // Cipher is not thread safe
                    //EDITED AFTER RIGHT ANSWER FROM
                    //*** Cipher cipher = Cipher.getInstance("AES");   ***//
                    // TO  
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");


        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);

        String encrypedValue = Base64.encodeToString(
                cipher.doFinal(clearText), Base64.DEFAULT);
        Log.d(TAG, "Encrypted: " + text + " -> " + encrypedValue);
        return encrypedValue;

    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    }
    return "";
}


public SecretKeySpec getKey(String password)
        throws UnsupportedEncodingException {


    int keyLength = 128;
    byte[] keyBytes = new byte[keyLength / 8];
    // explicitly fill with zeros
    Arrays.fill(keyBytes, (byte) 0x0);

    // if password is shorter then key length, it will be zero-padded
    // to key length
    byte[] passwordBytes = password.getBytes("UTF-8");
    int length = passwordBytes.length < keyBytes.length ? passwordBytes.length
            : keyBytes.length;
    System.arraycopy(passwordBytes, 0, keyBytes, 0, length);
    SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
    return key;
}

Und hier ist der iOS-Anhänger von meinem Kollegen:

- (NSData *)AES128EncryptWithKey:(NSString *)key {

    // 'key' should be 32 bytes for AES256,
    // 16 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES128 + 1]; // room for terminator (unused)
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

    // insert key in char array
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [self length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesEncrypted = 0;

    // the encryption method, use always same attributes in android and iPhone (f.e. PKCS7Padding)
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding,
                                          keyPtr,
                                          kCCKeySizeAES128,
                                          NULL                      /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize,       /* output */
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {

        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }

    free(buffer);
    return nil;
}

Ich mag es wirklich zu verstehen, was der Unterschied sein könnte und wie man ihn vermeidet. Der Test, der genau mit größeren Strings als 15 Zeichen durchgeführt wurde, gab mir einen Hinweis, aber ich weiß nicht warum :)

Vielen Dank im Voraus Jungs!

Antworten auf die Frage(1)

Ihre Antwort auf die Frage