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;
}