Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java AES不解密阿拉伯语_Java_Eclipse_Encryption_Aes - Fatal编程技术网

Java AES不解密阿拉伯语

Java AES不解密阿拉伯语,java,eclipse,encryption,aes,Java,Eclipse,Encryption,Aes,我正在使用Eclipse对字符串进行加密和解密。我正在使用以下功能: private final static String ALGORITHM = "AES"; public static String cipher(String secretKey, String data) throws Exception { SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSH

我正在使用Eclipse对字符串进行加密和解密。我正在使用以下功能:

private final static String ALGORITHM = "AES";


    public static String cipher(String secretKey, String data) throws Exception {



        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

        KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), secretKey.getBytes(), 128, 256);

        SecretKey tmp = factory.generateSecret(spec);

        SecretKey key = new SecretKeySpec(tmp.getEncoded(), ALGORITHM);



        Cipher cipher = Cipher.getInstance(ALGORITHM);

        cipher.init(Cipher.ENCRYPT_MODE, key);



        return toHex(cipher.doFinal(data.getBytes()));

    }


    public static String decipher(String secretKey, String data) throws Exception {



        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

        KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), secretKey.getBytes(), 128, 256);

        SecretKey tmp = factory.generateSecret(spec);

        SecretKey key = new SecretKeySpec(tmp.getEncoded(), ALGORITHM);



        Cipher cipher = Cipher.getInstance(ALGORITHM);



        cipher.init(Cipher.DECRYPT_MODE, key);



        return new String(cipher.doFinal(toByte(data)));

    }


    private static byte[] toByte(String hexString) {

        int len = hexString.length()/2;



        byte[] result = new byte[len];



        for (int i = 0; i < len; i++)

            result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();

        return result;

    }


    public static String toHex(byte[] stringBytes) {

        StringBuffer result = new StringBuffer(2*stringBytes.length);



        for (int i = 0; i < stringBytes.length; i++) {

            result.append(HEX.charAt((stringBytes[i]>>4)&0x0f)).append(HEX.charAt(stringBytes[i]&0x0f));

        }



        return result.toString();

    }
    private final static String HEX = "0123456789ABCDEF";
private final static String ALGORITHM=“AES”;
公共静态字符串密码(字符串secretKey、字符串数据)引发异常{
SecretKeyFactory factory=SecretKeyFactory.getInstance(“PBKDF2WithHmacSHA1”);
KeySpec spec=new-PBEKeySpec(secretKey.tocharray(),secretKey.getBytes(),128,256);
SecretKey tmp=工厂生成信任(规范);
SecretKey key=newsecretkeyspec(tmp.getEncoded(),算法);
Cipher Cipher=Cipher.getInstance(算法);
cipher.init(cipher.ENCRYPT_模式,密钥);
返回到hex(cipher.doFinal(data.getBytes());
}
公共静态字符串解密(字符串加密键、字符串数据)引发异常{
SecretKeyFactory factory=SecretKeyFactory.getInstance(“PBKDF2WithHmacSHA1”);
KeySpec spec=new-PBEKeySpec(secretKey.tocharray(),secretKey.getBytes(),128,256);
SecretKey tmp=工厂生成信任(规范);
SecretKey key=newsecretkeyspec(tmp.getEncoded(),算法);
Cipher Cipher=Cipher.getInstance(算法);
cipher.init(cipher.DECRYPT_模式,密钥);
返回新字符串(cipher.doFinal(toByte(data));
}
专用静态字节[]toByte(字符串hexString){
int len=hexString.length()/2;
字节[]结果=新字节[len];
对于(int i=0;i>4)和0x0f)).append(十六进制字符(stringBytes[i]&0x0f));
}
返回result.toString();
}
私有最终静态字符串HEX=“0123456789ABCDEF”;
我正在处理的字符串包含英语和阿拉伯语字符。当我解密字符串时,阿拉伯字符被问号(?)替换


如何解决此问题?

这里有三种不同的转换:

  • 将未加密文本转换为未加密字节
  • 未加密字节到加密字节
  • 将字节加密为十六进制
。。。当然,情况正好相反

我怀疑问题出在第一步。目前,您正在使用
新字符串(byte[])
String.getBytes()
,两者都使用平台默认编码。这几乎总是个坏主意。通常,最好使用UTF-8(例如,使用
标准字符集.UTF_8
)进行所有编码和解码,除非您有充分的理由使用其他内容

这是一个出发点,但另一个出发点是分别查看每个转换,并找出数据被破坏的位置。大量的诊断将在这里有所帮助


我有一个更详细的示例。

问题是您使用了
data.getBytes()
(和
secretKey.getBytes()
)。此方法使用操作系统上的默认编码。例如,在西欧的Windows上,此默认值为
Cp1252
,不包含阿拉伯语,因此将不支持的字符转换为

您将需要使用
data.getBytes(“UTF-8)
,在创建字符串时也需要使用同样的方法


底线:始终明确你的角色集!

我做了两次调整,效果很好:

  • 在cipher函数中,我编写了以下代码:returntohex(cipher.doFinal(data.getBytes(“UTF-8”))

  • 在解密函数中,我写了以下内容:返回新字符串(cipher.doFinal(toByte(data)),“UTF-8”)


不是100%确定,因此有评论,但我认为您需要指定字符串的格式(UTF-8)。阿拉伯语与否与加密无关。加密只看到数字(字节)对您来说,这不是他们的意思。胡乱猜测:您输出解密的控制台不支持Unicode 16,因此无法正确显示字符。此外,除非您使用toHex和toByte方法调试加密/解密产生的字节,否则它们实际上是无用的。@m0skit0请参阅Jon Skeet的答案。@npinti AFAIK您不需要如果在加密/解密中都使用默认UTF-16,请指定字符串编码。@m0skit0加密时不指定编码,因为加密的是字节而不是字符串-这些字节是否来自字符串、图像、HW RNG或其他内容与实际加密过程完全无关。此代码未指定编码当将字符串转换为字节时,它会得到默认值,这可能无法对阿拉伯语进行编码。此外,我不知道Jon Skeet是上帝,他只是有正确的答案。你不需要将此作为答案发布。如果你愿意,编辑问题并将其放在问题的末尾。(如果您这样做,请不要编辑问题中的代码,因为这样人们就看不到原始问题是什么了)此答案与已提供的其他2个答案相同,我不明白为什么有3个答案是相同的。