当前位置: 首页 > 面试题库 >

无法在Java和PHP之间交换使用AES-256加密的数据

乐正德华
2023-03-14
问题内容

我的问题是:用Java加密的内容我可以用Java完美解密,但PHP
mcrypt无法解密。我使用的加密内容mcrypt可以使用解密mcrypt,但不能用Java 解密。

我想从Java应用程序向PHP页面发送和接收加密数据,因此我需要它兼容。

这就是我所拥有的…

JAVA …

public static String crypt(String input, String key){
    byte[] crypted = null;
    try{
        SecretKeySpec skey = new SecretKeySpec(Base64.decodeBase64(key), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, skey);
        crypted = cipher.doFinal(input.getBytes());
    }catch(Exception e){
    }
    return Base64.encodeBase64String(crypted);
}

public static String decrypt(String input, String key){
    byte[] output = null;
    try{
        SecretKeySpec skey = new SecretKeySpec(Base64.decodeBase64(key), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, skey);
        output = cipher.doFinal(Base64.decodeBase64(input));
    }catch(Exception e){
    }
    return new String(output);
}

运行:

public static void main(String[] args) {
    String key = "Zvzpv8/PXbezPCZpxzQKzL/FeoPw68jIb+NONX/LIi8=";
    String data = "example";
    System.out.println(Cpt.decrypt(Cpt.crypt(data, key), key));
}

输出:

example

PHP …

function getEncrypt($sStr, $sKey) {
    return base64_encode(
        mcrypt_encrypt(
            MCRYPT_RIJNDAEL_256, 
            $sKey,
            $sStr,
            MCRYPT_MODE_ECB
        )
    );
}

function getDecrypt($sStr, $sKey) {
    return mcrypt_decrypt(
        MCRYPT_RIJNDAEL_256, 
        $sKey, 
        base64_decode($sStr), 
        MCRYPT_MODE_ECB
    );
}

运行:

$crypt = getDecrypt(getEncrypt($str, $key), $key);
echo "<p>Crypt: $crypt</p>";

输出:

Crypt: example�������������������������

使用PHP使用密钥“ Zvzpv8 / PXbezPCZpxzQKzL / FeoPw68jIb + NONX / LIi8 =”
使用Java使用相同的密钥对相同的事物进行加密,我得到“ + tdAZqTE7WAVPXhB3Tp5 + g ==“。

我正在以正确的顺序对base64进行编码和解码,并且测试了Java和PHP之间的base64编码和解码兼容性,并且它可以正常工作。


问题答案:

错误1

MCRYPT_RIJNDAEL_256 不是
AES。该常数中的256是指块大小,而不是键大小。使用MCRYPT_RIJNDAEL_128得到同样的算法AES。密钥大小仅由您提供的key参数中的字节数设置。因此,提供32个字节,您将获得带有256位密钥的AES。

错误#2

这两行在Java中永远是不正确的,表明对密码转换产生的任意二进制数据的本质有根本的误解:

output = cipher.doFinal(Base64.decodeBase64(input));
return new String(output);

byte[]直接传输和存储没有任何问题,但是,如果必须仅使用可打印的字符串,则应使用base64编码/解码来进行。由于您已经在广泛使用base64,这似乎是可行的方法。我猜正确的两行是:

output = cipher.doFinal(Base64.decodeBase64(input));
return new String(Base64.encodeBase64(output), "UTF-8");

编辑:

只是在开玩笑#2。真的,我错了,我没有注意到这是解密的方向。当然,如果您知道解密后byte[]的字符串是有效的字符串,那么执行代码所执行的操作是完全正确的。



 类似资料:
  • 我已经使用OpenSSL AES-256-GCM加密了一个文件。由于aes-256-gcm不受命令行支持,我已经安装了LibreSSL,我可以使用下面的命令加密文件的数据。 openssl ENC-AES-256-GCM-K 616161616161616161616161616161616161616161616161616161616161616161-IV 768A5C31A97D5FE9-

  • 问题内容: 我有下面的Java代码来加密使用64个字符的密钥的字符串。我的问题是这将是AES-256加密吗? 以下是结合了divanov和laz建议的代码。 问题答案: 是的,它将是64个字符,即32个字节和256位,并且256位的任何序列都可以用作AES-256密钥。 我建议您使用DatatypeConverter.parseHexBinary(或您选择的库中的类似实用程序)将十六进制字符串转换

  • 我遇到的情况是,JSON在PHP的中加密,需要在JAVA中解密。 此包含正确的数据,现在已解密。 现在,问题是当我试图做同样的事情在Java它不起作用:( 这是: 我已经访问了类似的问题,如 AES-256 CBC用php加密,用Java解密,反之亦然 openssl_在java中加密256个CBC原始_数据 无法在Java和PHP之间交换使用AES-256加密的数据 名单还在继续。。。。但是运气

  • 客户端: 服务器端:

  • 问题内容: 我正在尝试使用PyCrypto构建两个接受两个参数的函数:消息和密钥,然后对消息进行加密/解密。 我在网络上找到了几个链接可以帮助我,但是每个链接都有缺陷: 在codekoala上的此代码使用了os.urandom,PyCrypto不建议这样做。 此外,我不能保证给函数的键具有预期的确切长度。我该怎么做才能做到这一点? 另外,有几种模式,推荐哪种?我不知道该怎么用:/ 最后,IV到底是