【问题标题】:How to adapt rijndael (php) algorithm to aes (java)如何使rijndael(php)算法适应aes(java)
【发布时间】:2014-06-09 19:15:11
【问题描述】:

我有一个 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();
        }
    }

它实际上返回: 4LepwOstJA0R2bg5FrdQXRutIOZlJi06f0D8NnnIG5Q=

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

【问题讨论】:

  • 关于选择哪种分组密码模式,我在这里写了一个描述:stackoverflow.com/a/22958889/371137。我不知道密钥用法是否能代表以后的生产用途,但如果它真的很弱,并且仅靠 60 位熵就几乎可以通过蛮力破解。

标签: java php encryption aes rijndael


【解决方案1】:

前 16 个字节在两次解密中是相同的。区别在于最后 16 个字节:

4LepwOstJA0R2bg5FrdQX eoxesxmKV4pkf514F3VDqU %3D
4LepwOstJA0R2bg5FrdQX RutIOZlJi06f0D8NnnIG5Q =

由于您使用的是 ECB 模式(不要,它是不安全的),这告诉我您正在正确加密第一个块而第二个块不同。您的 Java 代码指定 PKCS5 填充。然而,PHP 使用零填充来填充最后一个块。 The comments of mcrypt_encrypt 包含执行 PKCS#7 填充的示例,which is identical to PKCS#5 padding

【讨论】:

  • mcrypt 默认使用零填充(用零字节填充块长度)。这听起来很糟糕。不过,我不明白为什么 Java 输出比 PHP 输出短。 (@user25907)
  • @Perseids 如果密钥不合适,他们还会删除密钥信息。如果您查看底层的 c mcrypt 库,您会发现这些库自 2007 年左右以来一直无人维护。
  • Java 更短,因为它没有用替代呈现“%3D”替换来自 Base64 的终止“=”。这只是两个系统之间的区别。底层位模式是相同的,因为 Base64 到字节的转换不会受到影响。 ASCII 0x3D 是等号。
  • @owlstead: Apropos related questions ;-)
猜你喜欢
  • 2014-04-16
  • 2015-03-11
  • 1970-01-01
  • 2011-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多