简体   繁体   English

如何正确解密javax.crypto加密的字符串

[英]How to correctly decrypt a javax.crypto encrypted string

I am getting the following error when trying to decrypted: 尝试解密时出现以下错误:

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher javax.crypto.IllegalBlockSizeException:使用填充密码解密时,输入长度必须是16的倍数

Here is the encryption class I have implemented: 这是我实现的加密类:

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

public class StringEncrypter {

    public static String encrypt(String key, String string, String algorithm) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
        Key aesKey = new SecretKeySpec(key.getBytes("UTF-8"), algorithm);
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, aesKey);
        byte[] encrypted = cipher.doFinal(string.getBytes());
        return encrypted.toString();
    }

    public static String decrypt(String key, String encryptedString, String algorithm) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
        Key aesKey = new SecretKeySpec(key.getBytes("UTF-8"), algorithm);
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.DECRYPT_MODE, aesKey);
        String decrypted = new String(cipher.doFinal(encryptedString.getBytes()));
        return decrypted;
    }
}

This is how I encrypted a string: 这是我加密字符串的方式:

StringEncrypter.encrypt("0306868080306868", "ddd", "AES"); // [B@e19957c

When I attempt to decrypt the above encrypted string like this: 当我尝试像这样解密上面的加密字符串时:

String decrypted = StringEncrypter.decrypt("0306868080306868", "[B@e19957c", "AES");

I get the illegalBlockSizeException . 我得到了illegalBlockSizeException

What am I doing wrong above? 上面我在做什么错? How do I correctly decrypt an encrypted String? 如何正确解密加密的字符串?

You need to perform base 64 encoding decoding for your key and your ciphertext. 您需要对密钥和密文执行base 64编码解码。 There is a new Base64 class for this in Java 8. You cannot just store any byte in a string, not all bytes represent printable or even valid characters, and the output of a cipher is indistinguishable from random. Java 8中为此提供了一个新的Base64类。您不能仅将任何字节存储在字符串中,并非所有字节都表示可打印或什至是有效字符,并且密码的输出与随机输出是无法区分的。

Besides that, the byte array "class" (represented by [B in Java) doesn't implement the toString method, which means you just get the print out of Object.toString , ie the class name [B and a human readable identifier to the object instance instead of the actual ciphertext. 除此之外,字节数组“类”(由Java中的[B表示[B )没有实现toString方法,这意味着您只是从Object.toString获取了打印内容,即类名[B和人类可读的标识符,对象实例, 而不是实际的密文。

You cannot use bytes (binary) as a String. 您不能将字节(二进制)用作字符串。 it is not equivalent 它不等同

You should convert it . 您应该将其转换。 Several manners. 几种方式。 Base64 or Hexa, for example You with base64, it gives this: Base64或Hexa,例如具有base64的You,它给出以下信息:

import javax.xml.bind.DatatypeConverter ;

byte[] bt= ... // what you get

// Conversion B64
String encodedb64=DatatypeConverter.printBase64Binary(bt);

// CONVERSION base 64 => byte 
// base 64 => byte
byte [] byteArrayreverse=DatatypeConverter.parseBase64Binary(encodedb64);

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

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