简体   繁体   English

Java解密

[英]Java Decryption

I have a problem with with 我有一个问题

javax.crypto.Cipher

When I write this lines of code 当我写这行代码时

    Cipher cipher;
    byte[] bytes = null;

    try
    {
        cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, generateAESKey128b(key));
        bytes = cipher.doFinal(input.getBytes("UTF-8"));
    }
    catch (NoSuchAlgorithmException e)
    {
        e.printStackTrace();
    }
    catch (NoSuchPaddingException e)
    {
        e.printStackTrace();
    }
    catch (InvalidKeyException e)
    {
        e.printStackTrace();
    }
    catch (UnsupportedEncodingException e)
    {
        e.printStackTrace();
    }
    catch (IllegalBlockSizeException e)
    {
        e.printStackTrace();
    }
    catch (BadPaddingException e)
    {
        e.printStackTrace();
    }

The console give me this error 控制台给我这个错误

javax.crypto.IllegalBlockSizeException 
Input length must be multiple of 16 when    
decrypting with padded cipher
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at it.unitn.se.gym.backend.utils.Security.AES128Decode(Security.java:109)
at it.unitn.se.gym.backend.utils.Security.decode_AES128_Base64(Security.java:96)
at it.unitn.se.gym.backend.WebService.main(WebService.java:42)
Exception in thread "main" java.lang.NullPointerException
at it.unitn.se.gym.backend.utils.Security.decode_AES128_Base64(Security.java:97)
at it.unitn.se.gym.backend.WebService.main(WebService.java:42)

The first 2 lines of code are correct but when I pass the attribute "text", of type byte[], to the doFinal function, it give me the error. 前两行代码是正确的,但是当我将byte []类型的属性“ text”传递给doFinal函数时,它给了我错误。

Can someone tell me why? 有人可以告诉我为什么吗?

SOLVED: 解决了:

Okay, problem solved 好,问题解决了

byte[] encrypted = UniversalBase64Encoder.decode(input);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, generateAESKey128b(key));
byte[] originalBytes = cipher.doFinal(encrypted);

This is the right code that I wrote 这是我编写的正确代码

The problem is that you're trying to decrypt a string that was not encrypted, and in doing so are violating an assumption of the decryption algorithm (that its input size is always a multiple of 16). 问题是您试图解密未加密的字符串,并且这样做违反了解密算法的假设(其输入大小始终为16的倍数)。

Here's a block of code that encrypts and then decrypts a string. 这是一段代码,它先加密然后解密一个字符串。 Notice that when the encrypted string is printed, it's 16 bytes long, even though the input string is not. 请注意,当打印加密的字符串时,它的长度为16个字节,即使输入的字符串不是。 The encryption algorithm pads the input string out to make it a multiple of 16 bytes before encrypting it. 加密算法将输入字符串填充出来,使其在加密之前为16字节的倍数。 That 16-byte-long encrypted string is now a valid input for decryption. 现在,该16字节长的加密字符串是解密的有效输入。

This assumption (that the result of encrypting will be an even size) is quite standard. 这种假设(加密的结果将是偶数大小)是非常标准的。 It not only makes the decryption/encryption algorithm easier to write, but it also prevents an attacker from knowing the length of the thing you encrypted. 它不仅使解密/加密算法更易于编写,而且还阻止了攻击者知道您加密的事物的长度。

byte[] keyBytes = new byte[16];
keyBytes[0] = 1;
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
String input = "hello";
Cipher cipher;
byte[] bytes = null;
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
bytes = cipher.doFinal(input.getBytes("UTF-8"));

System.out.println("Encoded: "+Arrays.toString(bytes));

cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decoded = cipher.doFinal(bytes);

System.out.println("Decoded: "+new String(decoded, "UTF-8"));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM