I\'ve been successfully using javax.crypto.Cipher.getInstance(\"DESede/CBC/NoPadding\") to Authenticate with DESFire cards on Android (following the example here: https://st
there is a android bug issued: https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=triple%20des&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened&groupby=&sort=&id=189292
you can also solve your problem by changing you key to 24 bytes len as below:
MessageDigest md = MessageDigest.getInstance("MD5");
seed_key = md.digest(new String(key).getBytes());
if (seed_key.length == 16) {
byte[] tempkey = new byte[24];
System.arraycopy(seed_key, 0, tempkey, 0, 16);
System.arraycopy(seed_key, 0, tempkey, 16, 8);
seed_key = tempkey;
}
SecretKeySpec keySpec = new SecretKeySpec(seed_key, "DESede");
nCipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
byte[] IVector = new byte[] { 27, 9, 45, 27, 0, 72, (byte) 171, 54 };
IvParameterSpec iv = new IvParameterSpec(IVector);
nCipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
byte[] cipherbyte = nCipher.doFinal(data.getBytes());
encodeTxt = new String(Base64.encodeBase64(cipherbyte));
It seems they changed the default provider in Marshmallow.
A simple:
cipher.getProvider().getName();
Shows "AndroidOpenSSL" for Marshmallow, where it was "BC" (BouncyCastle I suppose) before.
Using the other getInstance overload...
javax.crypto.Cipher cipher =
javax.crypto.Cipher.getInstance("DESede/CBC/NoPadding","BC");
...gives me the expected result on my Nexus with Marshmallow.
Update: I now get this warning:
The BC provider is deprecated and when targetSdkVersion is moved to P this method will throw a NoSuchAlgorithmException. To fix this you should stop specifying a provider and use the default implementation
Cipher#getInstance should not be called with ECB as the cipher mode or without setting the cipher mode because the default mode on android is ECB, which is insecure.
So I have ended up using the other answer here that will (hopefully) work on all versions of Android.