0

I am trying to encrypt and decrypt a String by using Java and AES Cipher.getInstance("AES/CBC/PKCS5PADDING").

When I encrypt the data and try to print it to the console, I am getting characters something like this :

�0��J�9U\�6N� ��.�����͋«D�<(���H(�G�jַ��%���u��^� ��'�bT/�05���0+u)b�ς�{G�d��/�:��~��ٵ�J%���~_ ���_����~�W�s�+]9�{Y�N����J{����釔Ä��

Is this correct? Can be said "it is encrypted"? My expectation was to get literal String like "WERWERWERWER"

4
  • 8
    Thats because encrypted messege is in bytes(0-255). To get string like you want you need to encode output with base 64. Commented Jan 5, 2018 at 17:14
  • 3
    Yes, there's really no such concept of "encrypting a String". You encrypt bytes into other bytes, and the result most likely won't be very display friendly. If you're just trying to convert letters to other letters, then use something like Caesar cipher. Commented Jan 5, 2018 at 17:18
  • 2
    @Kayaman "use something like Caesar cipher": but only if you are happy with kindergarten strength security Commented Jan 5, 2018 at 17:20
  • 3
    @Henry well, his expectation was to get a String like "WERWERWER"... Commented Jan 5, 2018 at 17:20

2 Answers 2

5

Thats because encrypted message is in bytes(0-255). To get string like you want you need to encode output with base 64.

Based on this answer you can do that in Java 8 without using any libraries.

import java.util.Base64;

//base64 encoding
byte[] encodedBytes = Base64.getEncoder().encode("Test".getBytes("UTF-8"));
System.out.println("encodedBytes " + new String(encodedBytes));
//base64 decoding
byte[] decodedBytes = Base64.getDecoder().decode(encodedBytes);
System.out.println("decodedBytes " + new String(decodedBytes));

Replace "Test".getBytes("UTF-8") with output from AES

Sign up to request clarification or add additional context in comments.

4 Comments

Always specify the encoding, so .getBytes("UTF-8"); for example.
I updated answer. This is just a sample, and OP already has his bytes ready.
It's important to make sure samples are proper. Many people don't understand the significance of specifying the encoding, and that causes a lot of confusion when it ends up biting them in the behind.
Use constants in StandardCharsets to specify common encodings. For example, str.getBytes(StandardCharsets.UTF_8).
0

Just use the UTF-8 encoding and your values should be right.

I've just made an small example so I think will be clear to understand.

Please check here:

package com.nicolas.cli;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class TestCrypt {

  public static void main(String args[]) {

    TestCrypt testCrypt = new TestCrypt(keyValue);
    String encrypted = testCrypt.encrypt("someValue");
    System.out.println(encrypted);
    String decrypted = testCrypt.decrypt(encrypted);
    System.out.println(decrypted);

  }

  private static final String CRYPTO_ALGORITHM = "AES";
  private static final Logger LOGGER = LoggerFactory.getLogger(TestCrypt.class);
  private static final byte[] keyValue =
      new byte[]{'T', 'h', 'e', 'B', 'e', 's', 't', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y'};


  private final Key key;
  private final Cipher cipher = getCipherInstance();

  public TestCrypt(byte [] key) {
    this.key = new SecretKeySpec(key, CRYPTO_ALGORITHM);
  }

  private Cipher getCipherInstance() {
    try {
      return Cipher.getInstance(CRYPTO_ALGORITHM);
    } catch (GeneralSecurityException e) {
      LOGGER.error("Crypto error: Unable to get cipher instance");
      throw new RuntimeException(e);
    }
  }

  public String encrypt(String password) {
    try {
      cipher.init(Cipher.ENCRYPT_MODE, key);
      byte[] encVal = cipher.doFinal(password.getBytes());
      return new BASE64Encoder().encode(encVal);
    } catch (GeneralSecurityException e) {
      LOGGER.error("Crypto error: Unable to encrypt password");
      throw new RuntimeException(e);
    }
  }

  public String decrypt(String encryptedPassword) {
    try {
      cipher.init(Cipher.DECRYPT_MODE, key);
      byte[] decodedValue = new BASE64Decoder().decodeBuffer(encryptedPassword);
      return new String(cipher.doFinal(decodedValue), StandardCharsets.UTF_8);
    } catch (GeneralSecurityException | IOException e) {
      LOGGER.error("Crypto error: Unable to encrypt password");
      throw new RuntimeException(e);
    }
  }

}

1 Comment

Your description is incorrect, but your code does it correctly by base64-encoding the bytes returned by the encryption. Unfortunately you use an unsupported base-64 encoder/decoder in your code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.