Encrypt and decrypt doesnt give the same plain tex

2019-04-02 13:48发布

问题:

String plain1= "Test";
byte[] cipher = SplashSecure.getInstance().encrypt2(plain1);
String plain2 = SplashSecure.getInstance().decrypt2(cipher);

plain = Test������������������������

After decryption plainText2 should be equal to plaintext.But its not.

Encrypt/Decrypt methods.

 public void initKey(String key) {
    String paddedKey = Utils.padString(key);
    mKeyspec = new SecretKeySpec(Utils.getBytes(paddedKey), "AES/ECB/NoPadding");
                   // Utils.getBytes returns "paddedKey.getBytes("CP1252")"
 }

public byte[] encrypt2(String data) {
    try {
        Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, mKeyspec);
        String paddedData = Utils.padString(data);
        return cipher.doFinal(Utils.getBytes(paddedData));

    } catch(InvalidKeyException e) {
        e.printStackTrace();
    // Series of catch blocks
    }
    return null;
}

public String decrypt2(byte[] cypherText) {
    try {
        Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, mKeyspec);
        byte[] plainTextBytes = cipher.doFinal(cypherText);
        return Utils.getString(plainTextBytes);
        // Utils.getString returns "new String(bytes, "CP1252");"
    } catch(InvalidKeyException e) {
        // Series of catch blocks.
    } 
    return null;
}

Edit:

public static String padString(String source) {
    char paddingChar = '\0';
    int size = 16;
    int padLength = size - source.length() % size;

    for (int i = 0; i < padLength; i++) {
        source += paddingChar;
    }

    return source;
}

Edit:

Im trying to get the encryption-decryption working across windows(other client that encrypts, and server) and android. The windows client is a VC++ app that uses a Rijndael class(http://svn.openfoundry.org/pcman/2007.06.03/Lite/Rijndael.h) and android uses http://www.cs.ucdavis.edu/~rogaway/ocb/ocb-java/Rijndael.java The Windows client has encrypted the data and stored it on the server. I need to build a client for android that fetches the encrypted data, decrypt it and display to the user.

Im sure im using the correct key to decrypt.

回答1:

AES has a block size of 128 bits (i.e 16 bytes). It can only process data in blocks of this size, so even though you have told it to use NoPadding it is unable to comply.

The most likely thing that is happening here is that the AES implementation you are using is internally padding your four bytes of input up to 16 bytes and encrypting the result. When you decrypt, you get the same 16 bytes back out, i.e. 'T', 'e', 's', 't' and 12 garbage bytes.

The output you see supports this: "Test" followed by 24 ? symbols. I don't know why it's printing two ? symbols for each garbage byte, but I'm guessing it's something to do with interpreting the garbage bytes in unicode. You could see what is going on by printing out the raw byte values of the decrypted blob.

The short answer is that 'NoPadding' doesn't make sense for a block cipher (or, rather, if you are going to use NoPadding then you have to pad and unpad things yourself).