0

I'm trying to encrypt multiple byte arrays from a file via socket. Encrypt procedure works fine, but decrypt procedure throws BadPaddingException: invalid argument. After I read, I understood that the key for decrypt procedure is different from the one of the encrypt procedure. But why? And how I solve it?

protected void generateKey() throws KeyStoreException {
    try {
        keyStore = KeyStore.getInstance("AndroidKeyStore");
    } catch (Exception e) {
        e.printStackTrace();
    }

    try {
        keyGenerator = KeyGenerator.getInstance(
                KeyProperties.KEY_ALGORITHM_AES,
                "AndroidKeyStore");
    } catch (NoSuchAlgorithmException |
            NoSuchProviderException e) {
        throw new RuntimeException(
                "Failed to get KeyGenerator instance", e);
    }

    try {
        keyStore.load(null);
        if(!keyStore.containsAlias(KEY_NAME)) { //Not solving exception
            keyGenerator.init(new
                    KeyGenParameterSpec.Builder(KEY_NAME,
                    KeyProperties.PURPOSE_ENCRYPT |
                            KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                    .setEncryptionPaddings(
                            KeyProperties.ENCRYPTION_PADDING_PKCS7)
                    .build());
            keyGenerator.generateKey();
        }
    } catch (NoSuchAlgorithmException |
            InvalidAlgorithmParameterException
            | CertificateException | IOException e) {
        throw new RuntimeException(e);
    }
}

public boolean cipherInit() {
    try {
        cipher = Cipher.getInstance(
                KeyProperties.KEY_ALGORITHM_AES + "/"
                        + KeyProperties.BLOCK_MODE_CBC + "/"
                        + KeyProperties.ENCRYPTION_PADDING_PKCS7);
    } catch (NoSuchAlgorithmException |
            NoSuchPaddingException e) {
        throw new RuntimeException("Failed to get Cipher", e);
    }

    try {
        keyStore.load(null);
        key = (SecretKey) keyStore.getKey(KEY_NAME,
                null);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return true;
    } catch (KeyPermanentlyInvalidatedException e) {
        return false;
    } catch (KeyStoreException | CertificateException
            | UnrecoverableKeyException | IOException
            | NoSuchAlgorithmException | InvalidKeyException e) {
        throw new RuntimeException("Failed to init Cipher", e);
    }
}


public void Init() {
     if (!fingerprintManager.hasEnrolledFingerprints()) {
        return ;
     }
     try {
         generateKey();

         if (cipherInit()) {
             cryptoObject = new FingerprintManager.CryptoObject(cipher);
             FingerprintHandler helper = new FingerprintHandler(cont);
             helper.startAuth(fingerprintManager, cryptoObject, key);
             return;
         } else
             return;
     }
     catch (Exception e){
         e.printStackTrace();
     }
}




cliente(String addr, int port, FingerprintManager.CryptoObject object, SecretKey key) {
    dstAddress = addr;
    dstPort = port;
    this.cryptoObject = object;
    this.cont = cont;
    this.key=key;
}

@Override
protected String doInBackground(String... arg0) {

    Socket socket = null;

    try {

        socket = new Socket(dstAddress, dstPort);

        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        DataInputStream dis = new DataInputStream(socket.getInputStream());
        long l=0;
        int nn = 0;
        Cipher c = cryptoObject.getCipher();
        int accion=0;
        try {
            dos.writeInt(2);
            accion=dis.readInt();
            long tam =dis.readLong();
            int con=0;
            switch (accion)
                {
                case 1:

                    while ((l < tam)) {
                        try {

                            byte[] b = new byte[128];
                            byte[] eb = new byte[128];
                            byte[] db = new byte[128];
                            byte[] iv = new byte[16];
                            byte[] seed=new byte[16];

                            nn = dis.read(b);
                            SecureRandom s = new SecureRandom(seed);
                            c.init(Cipher.ENCRYPT_MODE, key, s);
                            eb = c.doFinal(b);
                            iv=c.getIV();
                            dos.write(iv,0,iv.length);
                            dos.flush();
                            dos.write(eb, 0, nn);
                            dos.flush();
                            l = l + nn;
                            con++;

                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            response = "Terminado";
                        }
                    }
                    dis.close();
                    dos.close();
                    socket.close();

                break;

                case 2:

                    while ((l < tam)) {
                        try {
                            byte [] iv=new byte[16];
                            dis.read(iv);
                            c.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(iv));
                            byte[] b = new byte[128];
                            byte[] db = new byte[128];
                            nn = dis.read(b);
                            db = c.doFinal(b);
                            dos.write(db, 0, nn);
                            dos.flush();
                            l = l + nn;
                            //System.out.println("nn=" + nn + " l=" + l + " tam=" + tam);
                        } catch (Exception e) {
                            System.out.println(e);
                            e.printStackTrace();
                        } finally {
                            response = "Terminado";
                        }
                    }
                    dis.close();
                    dos.close();
                    socket.close();

                        break;
                }

        }
        catch(Exception e){
            System.out.println(e);
        }
    } catch (IOException e) {
        System.out.println(e);
    }
    return response;
}
2
  • 1
    Welcome to StackOverflow; please can you add a tag for the language you're using here?
    – Ian
    Commented Oct 24, 2018 at 23:20
  • Your code makes the assumption that the clear text data and the cipher text data will have the same length, while in reality that may not necessarily be the case (due to padding).
    – Michael
    Commented Oct 25, 2018 at 13:09

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.