paradisa
paradisa

Reputation: 43

JAVA Cipher decrypt encrypted Chinese text, sometimes fail to bring back to Chinese text again and get error like ÃÂ

So i make a simple program that encrypt people text as string and write it to file.txt and if someone want to read the data, the program will get file.txt as string and decrypt the data

this is the backend program where user type/input text or read the text is at web (just simple textarea)

everything is fine and good in testing even in production, but error happen when someone start to insert Chinese text

the odd thing is, is not always error

i mean user when writing document and use some Chinese text, it going ok, he save it, not change it, keep adding new text he still can read the text, save it, read it and writing the other day but one day he can't read the Chinese text, only the Chinese text mostly he writing English text document, maybe someone name in Chinese he can't write in English, so he use Chinese text

i even try to loop encrypt decrypt data process, about 100 times and it still succeeded to encrypt and decrypt back to Chinese text

so i don't really know what cause the error

here's my code


import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class DecriptEncript {

    public static void main(String[] args) {

        final String secretKey = "zxc";

        //String originalString = "i";
        String originalString = "你好吗";
         
         
        for(int i = 0 ; i <100;i++) { // when i test try 100 times

            String encryptedString = DecriptEncript.encrypt(originalString, secretKey) ;
            String decryptedString = DecriptEncript.decrypt(encryptedString, secretKey) ;
            System.out.println(originalString);
            System.out.println(encryptedString);
            System.out.println(decryptedString);
        }
    }
    
    private static SecretKeySpec secretKey;
    private static byte[] key;
 
    public static void setKey(String myKey) 
    {
        MessageDigest sha = null;
        try {
            key = myKey.getBytes("UTF-8");
            sha = MessageDigest.getInstance("SHA-1");
            key = sha.digest(key);
            key = Arrays.copyOf(key, 16); 
            secretKey = new SecretKeySpec(key, "AES");
        } 
        catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } 
        catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
 
    public static String encrypt(String strToEncrypt, String secret) 
    {
        try
        {
            setKey(secret);
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
        } 
        catch (Exception e) 
        {
            System.out.println("Error while encrypting: " + e.toString());
        }
        return null;
    }
 
    public static String decrypt(String strToDecrypt, String secret) 
    {
        try
        {
            setKey(secret);
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
        } 
        catch (Exception e) 
        {
            System.out.println("Error while decrypting: " + e.toString());
        }
        return null;
    }
}

the error is when the program want to bring back to Chinese text "not always error" and when error happen the program showing text like

Ã…â¡Ã‚¬Ãâ€Ã¢â (just randomly take from all the error)

i don't know how to bring back user data to text Chinese from this text error and i don't know the Chinese text he input

BTW this is my first time use Cipher decrypt encrypted so if you ask me why choose "SHA-1" or "UTF-8" or Arrays.copyOf(key, 16); honestly i just copy from someone code at the internet

thank you for help

Upvotes: 1

Views: 604

Answers (1)

Olivier Gr&#233;goire
Olivier Gr&#233;goire

Reputation: 35467

You encode in UTF-8, but you decode in whatever encoding the platform is configured.

So just force UTF-8 in the decipher as well.

    public static String decrypt(String strToDecrypt, String secret) 
    {
        try
        {
            setKey(secret);
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            
            // Note the extraction for readability
            byte[] deciphered = cipher.doFinal(Base64.getDecoder().decode(strToDecrypt))
            
            // Here, use UTF-8
            return new String(deciphered, "UTF-8");

            // Or better:
            // return new String(deciphered, StandardCharsets.UTF_8);
        } 
        catch (Exception e) 
        {
            System.out.println("Error while decrypting: " + e.toString());
        }
        return null;
    }

Upvotes: 3

Related Questions