我写了一个用AES加密字符串的类:
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.*;
import javax.xml.bind.DatatypeConverter;
import org.bouncycastle.util.encoders.Hex;
public class CipherAES {
public static void brutToHexa(byte[] t) {
byte[] tab = Hex.encode(t);
System.out.print("secret key : ");
for (int i = 0; i < tab.length; i++) {
System.out.print((char) tab[i] + "");
}
System.out.println();
}
public static byte[] encrypter(final String message, SecretKey cle)
throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, cle);
byte[] donnees = message.getBytes();
return cipher.doFinal(donnees);
}
public static String decrypter(final byte[] donnees, SecretKey cle)
throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, cle);
return new String(cipher.doFinal(donnees));
}
public static void main(String[] args) {
final String message = "Java is the best";
KeyGenerator keyGen;
try {
keyGen = KeyGenerator.getInstance("AES");
SecretKey cle = keyGen.generateKey();
brutToHexa(cle.getEncoded());
byte[] enc = encrypter(message, cle);
System.out.print("encrypted text : ");
System.out.println(DatatypeConverter.printBase64Binary(enc));
String dec = decrypter(enc, cle);
System.out.println("decrypted text : " + dec);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
}
}
我以HEX格式显示密钥,并使用Base64编码加密文本。 为了跑,我得到:
secret key : dfaa3b49adbc546d4437107b6a666cb1
encrypted text : iwEjj0Gahfzgq4BWrdY9odNX9PqvHgppz9YZ3mddQq8=
decrypted text : Java is the best
这里是类解密:
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
public class DecryptCipherAES {
public static void main(String[] args) {
try {
byte[] key = ("dfaa3b49adbc546d4437107b6a666cb1").getBytes();
SecretKey secretKey = new SecretKeySpec(key, "AES");
String base64String = "iwEjj0Gahfzgq4BWrdY9odNX9PqvHgppz9YZ3mddQq8=";
byte[] enc = org.apache.commons.codec.binary.Base64.decodeBase64(base64String.getBytes());
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
String dec = new String(cipher.doFinal(enc));
System.out.println("texte decrypte : " + dec);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
}
}
运行时,我得到以下异常: javax.crypto.BadPaddingException:给定最终块未正确填充
答案 0 :(得分:0)
核心问题是您假设使用String#getBytes
会将基于十六进制的String
正确转换为字节数组。
您需要手动将十六进制String
值转换为byte
数组。考虑一下,您将byte
数组转换为String
格式,需要将其转换回来。
这基本上就是您的代码,但我带了您的DecryptCipherAES
并加入decryptWith
方法。
该示例将密钥和消息转换为十六进制String
,然后将其传递给decryptWith
,然后将其转换回byte
数组(通过取消它)。
同样,你也可以使用base64编码,但你仍然需要在另一端解码它
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.management.openmbean.InvalidKeyException;
import javax.xml.bind.DatatypeConverter;
public class Test11 {
public static String brutToHexa(byte[] t) {
StringBuilder sb = new StringBuilder(t.length * 2);
for (int i = 0; i < t.length; i++) {
int v = t[i] & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));//.append("-");
}
return sb.toString();
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
public static byte[] encrypter(final String message, SecretKey cle)
throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException, java.security.InvalidKeyException {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, cle);
byte[] donnees = message.getBytes();
return cipher.doFinal(donnees);
}
public static String decrypter(final byte[] donnees, SecretKey cle)
throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException, java.security.InvalidKeyException {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, cle);
return new String(cipher.doFinal(donnees));
}
public static void main(String[] args) throws java.security.InvalidKeyException {
final String message = "Java is the best";
KeyGenerator keyGen;
try {
keyGen = KeyGenerator.getInstance("AES");
SecretKey cle = keyGen.generateKey();
String hexKey = brutToHexa(cle.getEncoded());
byte[] enc = encrypter(message, cle);
System.out.print("encrypted text : ");
System.out.println(DatatypeConverter.printBase64Binary(enc));
String dec = decrypter(enc, cle);
System.out.println("decrypted text : " + dec);
decryptWith(hexKey, brutToHexa(enc));
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
}
public static void decryptWith(String hexKey, String hexMessage) throws java.security.InvalidKeyException {
try {
byte[] byteKey = hexStringToByteArray(hexKey);
SecretKey secretKey = new SecretKeySpec(byteKey, "AES");
byte[] message = hexStringToByteArray(hexMessage);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
String dec = new String(cipher.doFinal(message));
System.out.println("texte decrypte : " + dec);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
}
}
现在打印......
encrypted text : jq1S6WI0XsW6jmPQmCoZheVKEUZj5zOJZoR13jNdbYE=
decrypted text : Java is the best
texte decrypte : Java is the best
答案 1 :(得分:0)
问题在于将字符串转换为十六进制,我使用了这种方法并且它可以工作:
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}