简体   繁体   中英

AES encryption in Java for given key

I am trying to do AES encryption in Java. I have the following function:

public static String encrypt(String plainText, String key) throws Exception {
    if (plainText == null || plainText.length() == 0) {
        return plainText;
    }

    // get aes key
    SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

    // encrypt
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
    byte[] bytes = cipher.doFinal(plainText.getBytes("UTF-8"));

    //encode
    String encoded = Base64.encodeToString(bytes, Base64.NO_PADDING | Base64.NO_WRAP);

    return encoded;
}

My aim is to be able to encrypt some text with a given key the same way every time. That is, if I call this function with the same two parameters many times, I want the same string to be returned on every call. I'll say in advance, I know that is not how cryptography is supposed to be done, but I need this functionality for my project.

Unfortunately, that is not the case. The key generated in line 7 seems to encrypt my string differently every time around. I assume there is some kind of extra random automatic salting occurring on the lower levels of this library, preventing me from achieving my goal.

Does anyone know a way in Java how I could go about encrypting a given string with a given key to the same value every time? Thanks.

UPDATE/CLARIFICATION: This is not for security. This is for the encryption of data for it to be obfuscated for certain people that might come in contact with working on the app itself. The information is not highly sensitive, but I do want it encrypted and then decrypted by the same key. I have others working with me on this with libraries in their respective languages, eg Ruby, and their libraries allow them to encrypt a value with a given key the same way every time. We all want to use the same parameters of the same encryption algorithm: Key length: 128 bits Mode of operation: CBC Initialization Vector: None (all zeros)

Is it perhaps that if one does not set an initialization vector, it is randomly assigned? I've got to check that out.

Yes, Java - or rather the security provider supplying the AES in CBC mode implementation - may default to a random IV (which you then have to retrieve afterwards and include with your ciphertext) if you don't explicitly specify it you get secure, randomized ciphertext.

If you want to use a zero IV you will have to specify it explicitly:

cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]);

This is only slightly more secure than ECB mode, as any repetition in different messages in the initial ciphertext blocks will be instantly visible to an attacker.

If you want to have a more secure mode without random IV - which is required for CBC mode to obtain CPA security - then you could check out synthetic IV (SIV) mode or GCM-SIV. For those modes the entire message needs to be identical with a previous one to leak info to an attacker. It's however slowe, not included in the standard VM and the ciphertext could be larger than AES/CBC (inclusion of IV/tag vs padding requirements).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM