如何使rijndael(php)算法适应aes(java)

如何使rijndael(php)算法适应aes(java),java,php,encryption,aes,rijndael,Java,Php,Encryption,Aes,Rijndael,我有一个php代码,在EBC模式下使用rijndael算法对纯文本进行加密,密钥长度为17个字符。 我希望在Java中使用等效的AES算法 这是我的php代码: <?php $key=" 4288f0b8060ca1b "; $mcryptAlgo= MCRYPT_RIJNDAEL_128 ; $mcryptMode= MCRYPT_MODE_ECB ; $data = "text_to_crypt_with_aes" ; $mcryptedData = mc

我有一个php代码,在EBC模式下使用rijndael算法对纯文本进行加密,密钥长度为17个字符。 我希望在Java中使用等效的AES算法

这是我的php代码:

<?php 
  $key=" 4288f0b8060ca1b "; 
  $mcryptAlgo= MCRYPT_RIJNDAEL_128 ; 
  $mcryptMode= MCRYPT_MODE_ECB ; 
  $data = "text_to_crypt_with_aes" ;

  $mcryptedData = mcrypt_encrypt ($mcryptAlgo, $key, $data, $mcryptMode); 
  $parametres_chiffres = urlencode( base64_encode ($mcryptedData)); 
  echo($parametres_chiffres);
?> 

结果,它返回加密消息:4LepwOstJA0R2bg5FrdQXeoxesxmKV4pkf514F3VDqU%3D

但是,我构建的以下Java代码不会返回相同的消息:

public static void main(String[] args) {

        StringBuilder sb = new StringBuilder();
        sb.append("text_to_crypt_with_aes");
        String clearText = sb.toString();
        StringBuilder sbKey = new StringBuilder(" 4288f0b8060ca1b ");
        for (int i = 0; i < 7; i++) {
            sbKey.append("\0");
        }

        try {

            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

            Key key = new SecretKeySpec(sbKey.toString().getBytes("UTF-8"),
                    "AES");

            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] encryptedMessageInBytes = cipher.doFinal(clearText
                    .getBytes("UTF-8"));
            byte[] b64 = Base64.encodeBase64(encryptedMessageInBytes);
            String scrambled_text = new String(b64, Charset.forName("US-ASCII"));
            System.out.println(scrambled_text);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
publicstaticvoidmain(字符串[]args){
StringBuilder sb=新的StringBuilder();
sb.附加(“文本加上aes到密码”);
String clearText=sb.toString();
StringBuilder sbKey=新StringBuilder(“4288f0b8060ca1b”);
对于(int i=0;i<7;i++){
sbKey.append(“\0”);
}
试一试{
Cipher Cipher=Cipher.getInstance(“AES/ECB/PKCS5Padding”);
Key Key=new SecretKeySpec(sbKey.toString().getBytes(“UTF-8”),
“AES”);
cipher.init(cipher.ENCRYPT_模式,密钥);
字节[]encryptedMessageInBytes=cipher.doFinal(明文
.getBytes(“UTF-8”);
字节[]b64=Base64.encodeBase64(encryptedMessageInBytes);
字符串加扰_text=新字符串(b64,Charset.forName(“US-ASCII”);
System.out.println(加扰文本);
}捕获(例外e){
e、 printStackTrace();
}
}
它实际上返回: 4LepwOstJA0R2bg5FrdQXRutIOZlJi06f0D8NnnIG5Q=


如何调整Java代码以返回与php完全相同的结果?

前16个字节在两种解密中都是相同的。差异在最后16个字节中:

4LepwOstJA0R2bg5FrdQX eoxesxmKV4pkf514F3VDqU %3D
4LepwOstJA0R2bg5FrdQX RutIOZlJi06f0D8NnnIG5Q =

因为您使用的是ECB模式(不要,这是不安全的),它告诉我您正确加密了第一个块,而第二个块则不同。Java代码指定PKCS5填充。然而,PHP使用零填充来填充最后一个块。包含执行PKCS#7填充的示例。

mcrypt默认使用零填充(用零字节填充到块长度)。这是一个听起来很糟糕的主意。我不明白为什么Java输出比PHP输出短。(@user25907)@Perseids如果钥匙不合适,他们也会减少钥匙信息。如果您查找底层的c mcrypt库,您会发现这些库自2007年左右以来一直未被维护。Java较短,因为它没有将Base64中的终止“=”替换为可选的呈现“%3D”。这只是两种制度之间的区别。底层位模式是相同的,因为Base64到字节的转换不会受到影响。ASCII 0x3D是等号。@owlstead:Apropos;-)关于选择哪种分组密码模式,我已在此处对每种模式进行了描述:。我不知道这个关键用法是否代表了以后的生产用途,但如果是的话,它真的很弱,仅凭60位的熵就可以被蛮力破解。