当前位置: 首页 > 知识库问答 >
问题:

从PHP到Java(Android)的加密:如何修复错误“错误的最终块长度”?

龚镜
2023-03-14

我已经尝试了谷歌和SOF上的几种不同的方法,但我似乎无法让它起作用。我正在尝试用PHP加密一个字符串,用Java解密(Android活动)。在PHP中,为了加密字符串,我使用AES-256-CBC和sha256散列(它在PHP中成功地加密/解密)。问题是无论我尝试什么,我都无法获得Java中未加密的字符串。我最近的尝试以“cipher functions:openssl_internal:wrong_final_block_length”的控制台错误结束。

我怀疑我的问题是Base64编码,但我所有的尝试都失败了。或者我在Java端使用了错误的密码。我读到一些人需要转换到十六进制,虽然我不明白为什么。

请注意,iv和key并不是真正相同的,只是在这里使用相同的,例如。

我的PHP代码:

$secret_key = "1111111111111111";
$secret_iv = "1111111111111111";

$encrypt_method = "AES-256-CBC"; 
$key = hash( 'sha256', $secret_key );
$iv = substr( hash( 'sha256', $secret_iv ), 0, 16 );
$output = base64_encode( openssl_encrypt( $string, $encrypt_method, $key, 0, $iv ) );
    String given_iv = "1111111111111111";
    String key = "1111111111111111";

    IvParameterSpec iv = new IvParameterSpec(given_iv.getBytes());
    SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

    byte[] decodedEncryptedData = Base64.decode(data.getBytes(),Base64.NO_WRAP);

    byte[] original = cipher.doFinal(decodedEncryptedData);
    Log.i(TAG, "Result: " + new String(original));
    return new String(original);
    $secret_key = "1111111111111111";
    $secret_iv = "1111111111111111";

    $encrypt_method = "AES-256-CBC"; 
    $output = openssl_encrypt( $string, $encrypt_method, $secret_key, 0, $secret_iv );

Java代码仍然保持不变。但是我在使用cipher.getInstance(“aes/cbc/pkcs5padding”)并将其修改为“aes/cbc/nopadding”,它改变了错误,我现在得到了一个乱码文本的输出,但是仍然没有真正的成功解密。

共有1个答案

叶阳
2023-03-14

多亏了@topaco,终于找到了一个可行的解决方案。正如他们所指出的,不仅我是双重编码(Base64),而且我应该使用AES-128-CBC而不是AES-256-CBC。正如我所发现的,当IV长度无效时,php中的open_ssl似乎不会抛出错误,而是根据需要填充或删除字符。AES-128-CBC与16位IV工作正常,一切都解决了。

对于将来可能偶然发现这篇帖子的人来说,最终的解决方案是更改PHP端,如下所示:

$secret_key = "1111111111111111";
$secret_iv = "1111111111111111";

$encrypt_method = "AES-128-CBC"; 
$output = openssl_encrypt( $string, $encrypt_method, $secret_key, 0, $secret_iv );
 类似资料:
  • 有很多关于堆栈溢出的线程与这个主题,总是相同的解决方案,但这些对我不起作用。我正在寻找一种方法来解密值encrypted并返回decodedbytes。 使用Aescrypt方法。我使用 对于值密码,我是这样使用的。 我尝试放入Cipher.getInstance(aes/cbc/nopadding,aes/cbc/pkcs5padding,aes/cbc/pkcs7padding),但没有任何改

  • 问题内容: 使用此Gist,我能够在Node.js 0.8.7中成功解密AES256。然后,当我升级到Node.js 0.10.24时,现在看到此错误: TypeError:错误:0606506D:数字信封例程:EVP_DecryptFinal_ex: Decipheriv.Cipher.final(crypto.js:292:27)的最终块长度错误 这是Gist的解密代码(为方便起见,在此处显示

  • 问题内容: 实际上我不知道问题出在哪里。我认为这必须在创建TableLayout时进行。我不知道如何解决错误并使该应用程序正常工作。该程序显示错误“ java.lang.ArithmeticException:被零除”错误该程序具有EditText(edText),要求用户输入。它的类型是NUMBER。(这里r是edText的值)在EditText下方有一个Button(bt),它显示edText

  • 请帮助我识别以下RSA加密代码中的问题

  • db_connection=mysql, db_host=localhost db_port=3306 db_database=example db_username=root db_password= 这是一条错误消息 1条理\dbal\driver\pdoException::(“SQLSTATE[HY000][2002]没有这样的文件或目录”)/文档/清洁/示例/供应商/条理/dbal/li

  • 我已经更新了Android Studio的3.4.1版本。 立即,Android Gradle Plugin版本和Gradle版本不是最后一个版本,所以我用3.4.1和5.1.1(文件>项目结构>项目)进行了更改。 现在,我试图创建一个apk,但出现错误“无法找到com.Android.tools.Build:Gradle:3.4.1”。 该项目是用cordova创建的,首先我在9.0.0版本上更