SEC-1752: Null character appended to TextEncryptor.decrypt(String) results #1987

Closed
spring-issuemaster opened this Issue May 21, 2011 · 4 comments

1 participant

@spring-issuemaster

Keith Donald (Migrated from SEC-1752) said:

The following test fails:

@Test
public void test() {
    TextEncryptor encryptor = Encryptors.queryableText("password", "salt");
    String encrypted = encryptor.encrypt("6048b75ed560785c");
    String decrypted = encryptor.decrypt(encrypted);
    assertEquals("6048b75ed560785c", decrypted);
}

This is because the value of the decrypted variable has a null byte (%00) at the end. To get the test to pass, I called trim():

@Test
public void test() {
    TextEncryptor encryptor = Encryptors.queryableText("password", "salt");
    String encrypted = encryptor.encrypt("6048b75ed560785c");
    String decrypted = encryptor.decrypt(encrypted).trim();
    assertEquals("6048b75ed560785c", decrypted);
}

I'm not sure why this is happening at this stage, or the appropriate resolution. The AesBytesEncryptor is using AES with PKCS5 which should care for padding handling for both encrypt/decrypt operations. I'm puzzled as to why a null byte is being tacked on.

This problem manifested itself in the Greenhouse reference application as a OAuth Signature Verification Failure. The NUL (%00) byte is the culprit.

@spring-issuemaster

Keith Donald said:

I have confirmed its the doFinal(byte[]) call on the decrypt Cipher in AesBytesEncryptor is the one appending this null byte. Do not know why it is doing this though.

@spring-issuemaster

Keith Donald said:

Upon further investigation, it appears the call in HexEncodingTextEncryptor#encrypt to Utf8.encode(String) causes the message bytes, once encrypted, to decrypt with an extra null byte. I'm not familiar with the Ut8 class and it's use of the java.nio library to perform Utf8 encoding. If I replace use of that library with a standard string.getBytes("UTF-8") call, the extra byte goes away and the decrypted result is as expected. Luke, any insight into what's going on here, and to the usage of java.nio for UTF8 encoding?

@spring-issuemaster

Keith Donald said:

Attached is a patch to HexEncodingTextEncryptor that resolves this issue.

@spring-issuemaster

Luke Taylor said:

The reason for using CharsetEncoder is primarily to deal with the case when the bytes are not valid. We generally want to fail fast in that case, but the Javadoc from public String(byte[] bytes, String charsetName) says the behaviour is undefined. Typically it will use a fixed "replacement string" for invalid input. String.getBytes() actually uses CharsetEncoder under the hood, but configures the encoder not to throw an exception for invalid input.

The problem looks like being due to the fact that I haven't taken the limit within the ByteBuffer into account, but just pulled the underlying array contents directly (which happen to be one larger than the actual content length, hence the appearance of a null byte at the end).

@spring-issuemaster spring-issuemaster added this to the 3.1.0.RC3 milestone Feb 5, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment