java


ECB and CBC AES output is equal in Java


I've played around with the Java AES En/Decryption and used different cyper modes for this. Namely I use CBC and ECB. As ECB is considered to be weak, I wanted to go with CBC.
I assumed the output of the encrypted texts ob cbc and ecb are different, but they are equal. How is this possible?
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
import com.instana.backend.common.exception.InstanaException;
public class AESTest {
private static String pwd = "etjrgp9user9fu3984h1&(/&%$ยง";
public static void main(String[] args) throws Exception {
System.out.println("UNSECURE WITH ECB:");
String ecbEncrypt = encrypt("YOLO", cypher(Cipher.ENCRYPT_MODE, "AES"));
System.out.println("Encrypted: " + ecbEncrypt);
String ebcDecrypt = decrypt(ecbEncrypt, cypher(Cipher.DECRYPT_MODE, "AES"));
System.out.println("Decrypted: " + ebcDecrypt);
System.out.println("=====================================");
System.out.println("SECURE WITH CBC");
String cbcEncrypt = encrypt("YOLO", cypher(Cipher.ENCRYPT_MODE, "AES/CBC/PKCS5Padding"));
System.out.println("Encrypted: " + cbcEncrypt);
String cbcDecrypt = decrypt(cbcEncrypt, cypher(Cipher.DECRYPT_MODE, "AES/CBC/PKCS5Padding"));
System.out.println("Decrypted: " + cbcDecrypt);
System.out.println("=====================================");
System.out.println("Decrypting CBC with ECB");
}
public static String encrypt(String superDuperSecret, Cipher cipher) throws IOException {
try {
byte[] encrypted = cipher.doFinal(superDuperSecret.getBytes("UTF-8"));
return new String(new Hex().encode(encrypted));
} catch (Exception e) {
throw new InstanaException("Encryption of token failed.", e);
}
}
public static String decrypt(String superDuperSecret, Cipher cipher) {
try {
byte[] encrypted1 = new Hex().decode(superDuperSecret.getBytes("UTF-8"));
return new String(cipher.doFinal(encrypted1));
} catch (Exception e) {
throw new InstanaException("Encrypted text could not be decrypted.", e);
}
}
private static Cipher cypher(int mode, String method)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException,
InvalidAlgorithmParameterException {
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(pwd.toCharArray(), pwd.getBytes(), 128, 128);
SecretKey tmp = skf.generateSecret(spec);
SecretKey key = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance(method);
if(method.contains("CBC")) {
byte[] ivByte = new byte[cipher.getBlockSize()];
IvParameterSpec ivParamsSpec = new IvParameterSpec(ivByte);
cipher.init(mode, key, ivParamsSpec);
}else{
cipher.init(mode, key);
}
return cipher;
}
}
Since you're passing an empty IV (you never put anything inside your ivByte), the operations performed for the first block are identical regardless of the mode being used. Encrypting a longer payload would result in the second block being chained to the first block in the case of CBC and the following blocks would be different between ECB/CBC.
You should pass a non-empty IV when using CBC mode, so the first block will be xorred with the IV, resulting in different encrypted values starting from the first block.

Related Links

How to Deal with Enumeration with hash table
Android PorterDuff.Mode.SRC_IN error: Wrong 2nd argument type
Android: How to get app usage activity below API level 21?
Get method reference from class object in JAVA 8
Why is AtomicInteger needed if writes and reads to int variables are atomic?
Swing - GridLayout components not filling up all available space
Get number of CPU mesos allocated to Spark cluster from driver
How to connect android application with OLA API?
Java - Get a value out of JSON using JsonPath
JSF Local config not working
Use variable only after periodic thread has processed it
Can't get image src in html using jsoup
Does the EclEmma coverage tool perform node or edge or condition or path coverage?
IF and else statement not working while comparing string [duplicate]
Calling external program within Android App
Android AlarmClock search by label

Categories

HOME
testing
atom-editor
webpack
umd
alpha
enterprise-library-5
flyway4
adfs
facebook-messenger-bot
amazon-cloudformation
google-apps-marketplace
php-7.1
orchardcms
hex-editors
event-handling
msp430
decimal
try-catch
oxyplot
excel-vba-mac
chromium-embedded
firebase-crash-reporting
android-widget
sqlcipher
url-scheme
react-css-modules
traffic
maxmind
minitab
opentype
msys2
windows-server-2000
quote
madlib
copying
stringtemplate
xmlreader
form-data
ios5
io-redirection
file-format
theano.scan
ruby-on-rails-3.1
quadratic-programming
eigenvalue
estimote
midl
dandelion
integrity
togetherjs
nstextview
elgg
drupal-6
setter
flutterwave
bind9
quartz-composer
pycaffe
grails-tomcat-plugin
removechild
ubuntu-10.04
whois
microbenchmark
myo
streambase
cdt
phalanger
gulp-less
websocket4net
uitouch
undefined-reference
tidy
shellexecute
padarn
sabredav
limejs
drools-planner
kyotocabinet
itmstransporter
libstdc++
gil
first-responder
buildr
custom-backend
netdna-api
window-management
hirefire
vdsp
remember-me
html-input
google-friend-connect
dentrix
dbal
uimenucontroller
phonon
sector

Resources

Database Users
RDBMS discuss
Database Dev&Adm
javascript
java
csharp
php
android
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App