我试图用java加密和解密命令行的程序。到目前为止我可以正确加密但是当我尝试解密加密的消息时,我得到了填充错误。程序的代码是
package cat.copernic.simetriccd;
import java.security.MessageDigest;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
class symetric{
public static String byteArrayToHexString(byte[] b){
StringBuilder sb = new StringBuilder(b.length * 2);
for(int i = 0; i < b.length; i++){
int v = b[i] & 0xff; if(v < 16){
sb.append("0");
}
sb.append(Integer.toHexString(v));
} return sb.toString();
}
static SecretKey genKey(String text) {
SecretKey sKey = null;
int keySize = 256;
try {
byte[] data = text.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest(data);
byte[] key = Arrays.copyOf(hash, keySize/8);
sKey = new SecretKeySpec(key, "AES");
} catch (Exception ex) {
System.err.println("Error generant la clau:" + ex);
}
return sKey;
}
static String encryptData(String password, byte[] data) {
byte[] encryptedData = null;
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, genKey(password));
encryptedData = cipher.doFinal(data);
} catch (Exception ex) {
System.err.println("Error xifrant les dades: " + ex);
}
return byteArrayToHexString(encryptedData);
}
static String decryptData(String password, byte[] data) {
byte[] decryptedData = null;
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, genKey(password));
decryptedData = cipher.doFinal(data);
} catch (Exception ex) {
System.err.println("Error desxifrant les dades: " + ex);
}
return decryptedData.toString();
}
}
public class Main {
public static void main(String[] args) {
//controlar numero de parametros que se pasan
if(args.length <= 1 || args.length > 3 || args.length == 2){
System.out.println("java Main -mode=encrypt|decrypt <message> <key>");
return;
}
//sacamos los valores de los argumentos
String mode = args[0].split("=")[1].toLowerCase();
byte[] mensage = args[1].getBytes();
String key = args[2];
if(mode.equals("encrypt") || mode.equals("decrypt")){
switch (mode) {
case "encrypt":
//System.out.println("encrypt");
System.out.println(symetric.encryptData(key, mensage));
break;
case "decrypt":
//System.out.println("decrypt");
System.out.println(symetric.decryptData(key, mensage));
break;
default:
break;
}
}else {
System.out.println("Solo coje valores encrypt/ENCRYPT o decrypt/DECRYPT");
}
}
}
消息错误是
Error desxifrant les dades: javax.crypto.BadPaddingException: Given final block not properly padded
Exception in thread "main" java.lang.NullPointerException
at cat.copernic.simetriccd.symetric.decryptData(Main.java:61)
at cat.copernic.simetriccd.Main.main(Main.java:92)
我很确定错误是在这里生成的,但不知道如何解决它...任何想法?感谢
cipher.init(Cipher.DECRYPT_MODE, genKey(password));
decryptedData = cipher.doFinal(data);
答案 0 :(得分:1)
您需要在解密之前将十六进制编码的String转换回字节。建议使用this function。 decryptedData.toString()
也不会有效。尝试将字节编码为“UTF-8”字符串,如下所示:
new String(decryptedData, "UTF-8");
答案 1 :(得分:0)
最后,感谢帮助该练习的人们解决方案:
package cat.copernic.simetriccd;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
class symetric{
public static String byteArrayToHexString(byte[] b){
return DatatypeConverter.printHexBinary(b);
}
public static byte[] hexToByteArray(String b){
return DatatypeConverter.parseHexBinary(b);
}
static SecretKey genKey(String text) {
SecretKey sKey = null;
int keySize = 256;
try {
byte[] data = text.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest(data);
byte[] key = Arrays.copyOf(hash, keySize/8);
sKey = new SecretKeySpec(key, "AES");
} catch (Exception ex) {
System.err.println("Error generant la clau");
}
return sKey;
}
static String encryptData(String password, String data) {
byte[] encryptedData = null;
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, genKey(password));
encryptedData = cipher.doFinal(data.getBytes());
} catch (Exception ex) {
System.err.println("Error xifrant les dades");
}
return byteArrayToHexString(encryptedData);
}
static String decryptData(String password, String data) throws UnsupportedEncodingException {
byte[] decryptedData = null;
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, genKey(password));
decryptedData = cipher.doFinal(hexToByteArray(data));
} catch (Exception ex) {
System.err.println("Error desxifrant les dades");
}
return new String(decryptedData, "UTF-8");
}
}
public class Main {
public static void main(String[] args) throws UnsupportedEncodingException {
//controlar numero de parametros que se pasan
if(args.length <= 1 || args.length > 3 || args.length == 2){
System.out.println("java Main -mode=encrypt|decrypt <message> <key>");
return;
}
try {
//sacamos los valores de los argumentos
String mode = args[0].split("=")[1].toLowerCase();
String mensage = args[1];
String key = args[2];
if(mode.equals("encrypt") || mode.equals("decrypt")){
switch (mode) {
case "encrypt":
//System.out.println("encrypt");
System.out.println("mensaje encriptado= " + symetric.encryptData(key, mensage));
break;
case "decrypt":
//System.out.println("decrypt");
System.out.println("mensaje desencriptado= " + symetric.decryptData(key, mensage));
break;
default:
break;
}
}else {
System.out.println("Solo coje valores encrypt/ENCRYPT o decrypt/DECRYPT");
}
} catch (Exception e) {
System.out.println("Error en la definicion de los atributos");
}
}
}