Java解密用最简单的测试用例抛出奇怪的错误

问题描述 投票:0回答:1

怎么会发生这种事? 此代码无法解密字符串“hello”的“加密”文本。我搜索了类似的线程,但我仍然无法理解。

public class Test {

    class Encryption {
        File file;
        SecretKeySpec secretKeySpec;


        public void setFile(String filePathResource) throws Exception {
            URL url = Encryption.class.getResource(filePathResource);
            System.out.println(url.toString());
            this.file = new File(url.toURI());
            if (!file.isFile()) {
                System.out.println("File is not valid");
                throw new Exception("The file you choosed is not valid");
            }
        }

        public void setKey(String keyword) {
            try {
                MessageDigest sha = MessageDigest.getInstance("SHA-256");
                //sha.update(keyword.getBytes("UTF-8"));
                sha.update(keyword.getBytes());
                byte[] key = sha.digest();
                secretKeySpec = new SecretKeySpec(key, "AES");
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }

        public String encryptText(String text) {
            byte[] encryptedBytes = null;
            //String encodedResul = null;
            try {
                byte[] bytesText = text.getBytes();
                
                Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
                encryptedBytes = cipher.doFinal(bytesText);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return new String(encryptedBytes);
        }

        
                
        public String decryptText(String encryptedText) {
            byte[] decryptedBytes = null;
            try {
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                // byte[] bytesEncryptedText = encryptedText.getBytes("UTF-8");
                Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
                cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
                //byte[] decodedEncryptedText=Base64.getDecoder().decode(encryptedText);
                byte[] encryptedTextBytes=encryptedText.getBytes();
                decryptedBytes = cipher.doFinal(encryptedTextBytes);    

            } catch (Exception e) {
                e.printStackTrace();
            }
            return new String(decryptedBytes);
        }

        
    
    

    public static void main(String[] args) throws IOException, URISyntaxException {
        
        Test t = new Test();
        Encryption cipher = t.new Encryption();

        cipher.setKey("password");

         //String  encryptedText=cipher.encryptText("2024-05-04T05:48:19.702630400Z[UTC]");
         //String  encryptedText=cipher.encryptText("11-24'?*&11[]");
         String  encryptedText=cipher.encryptText("hello");
         System.out.println(new String(encryptedText));
         
         
//       char[]cl= encryptedText.toCharArray();
//       int i=1;
//       for(char c:cl) {
//           System.out.println(i++ + ". " +c);
//       }
        
        
         System.out.println(cipher.decryptText(encryptedText));
    }

}

该代码可以很好地处理复杂的文本“11-24'?*&11[]”,但如果处理简单的文本“hello”,它就会崩溃。 有哪位高手可以解释一下吗?

“11-24'?*&11[]”===> 效果很好

|Ä{™úk©¢[ÁÌ¿ µ

11-24'?*&11[]

“你好”===> 坏了

iî]´¾-Ò?%??H
javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
    at java.base/com.sun.crypto.provider.CipherCore.unpad(CipherCore.java:859)
    at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:939)
    at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:735)
    at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
    at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2205)
    at t$Encryption.decryptText(t.java:113)
    at t.main(t.java:174)
Exception in thread "main" java.lang.NullPointerException: Cannot read the array length because "bytes" is null
    at java.base/java.lang.String.<init>(String.java:1432)
    at t$Encryption.decryptText(t.java:118)
    at t.main(t.java:174)
`
java encryption
1个回答
0
投票

这可能有帮助

使用填充密码解密时,输入长度必须是 16 的倍数

总的来说,您需要确保安全地传输加密信息。标准的 toString() 方法可能会损坏您的数据,这很可能是您的情况发生的情况。

我修改了加密和解密方法并附加了片段。 希望它对你有用!!

public String encryptText(String text) {
        byte[] encryptedBytes = null;
        //String encodedResul = null;
        try {
            byte[] bytesText = text.getBytes();

            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            encryptedBytes = cipher.doFinal(bytesText);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //Safely Encode string
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }


    public String decryptText(String encryptedText) {
        byte[] decryptedBytes = null;
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            //Safely decode string
            byte[] encryptedTextBytes = Base64.getDecoder().decode(encryptedText);
            decryptedBytes = cipher.doFinal(encryptedTextBytes);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return new String(decryptedBytes);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.