字符串加密 PHP/Java
Posted
技术标签:
【中文标题】字符串加密 PHP/Java【英文标题】:String encryption PHP/Java 【发布时间】:2013-09-04 16:38:06 【问题描述】:因此,对于特定项目,我需要能够以与在另一个 php 应用程序中加密/解密相同的方式加密和解密字符串。我的应用程序是一个 Grails 应用程序,因此我将使用 Java 编写代码。在 PHP 端对字符串进行加密/解密的方式是(示例代码,不一定是功能性的):
<?
$input="textToBeEncrypted";
function encrypt($data, $key)
$cipher_alg = MCRYPT_DES;
$mode = MCRYPT_MODE_CBC;
return @mcrypt_encrypt($cipher_alg, $key, $data, $mode);
function decrypt($encrypted, $key)
$cipher_alg = MCRYPT_DES;
$mode = MCRYPT_MODE_CBC;
return @mcrypt_decrypt($cipher_alg, $key, $encrypted, $mode);
$key ="testKey";
$data=$input;
$result = decrypt($data, $key);
echo ">>" . $result . "<br>\n";
?>
所以,我希望能够在 Java(或 Groovy)中应用相同的加密/解密。我找到了这个示例代码 https://github.com/stevenholder/PHP-Java-AES-Encrypt/blob/master/security.java 并且我知道如果我设法在 Java 中找到算法和模式的名称,它应该可以工作。除非我遗漏了什么……我导航到用于加密算法的 Java 标准名称页面 http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html,但我找不到与我在 PHP 代码中所拥有的完全等价的内容。有任何想法吗?你们有没有人需要做类似的事情?
谢谢, 伊拉克利斯
【问题讨论】:
您可以使用 OpenSSL 功能。这些可能更便携。 php.net/manual/en/function.openssl-encrypt.php @ConnorPeet 注意默认情况下 OpenSSL 使用它自己的密钥派生函数 (EVP_BytesToKey
)。这也不是您在默认 Java 库中可以找到的。
感谢你们的 cmets,但是,我很可能对集成的 PHP 端发生的事情没有太多控制权。我的目标是尝试在 Java 中实现 PHP 端。不过,我会向他们提及 OpenSSL 功能。
【参考方案1】:
加密要考虑的三个主要事项是算法、模式和填充。这些必须在加密和解密软件之间兼容才能正常工作。
首先,绝对推荐AES
(Rijndael
) 支持DES
作为加密算法。 DES
不再被认为足够安全。您发布链接的 Java 代码使用的是AES
,因此它肯定与您显示的 PHP 代码不兼容。
另外,Java 代码使用ECB
的模式也是不推荐的。 ECB
更容易,因为它不需要对初始化向量进行任何处理,但这也是它的失败之处。 PHP 代码使用的是推荐的CBC
,尽管我没有看到任何明确的 IV 处理。在这种情况下,Mcrypt 将使用全零的 IV,这根本不理想。
最后,Java 代码使用PKCS5
作为填充方法,而 PHP 代码使用零填充。那些不兼容。 Oracle JDK 附带的默认提供程序不支持零填充,但Bouncy Castle 支持(参见第 5.0 节)。这将需要直接使用 Bouncy Castle 的 API,或者使用该链接中详述的方法之一将其用作 JCE 提供程序。字符串"DES/CBC/ZeroByte"
应该可以解决问题。
当然,如果您要加密的数据可以以空字节结尾,则零填充可以是 problematic。
我在here 之前回答了一个与此问题类似的问题,并在答案中提供了用Java 加密和用PHP 解密的代码。希望对您有所帮助。
【讨论】:
嗨 laz,非常感谢您的回答。当然我知道我发布的Java代码使用了不同的算法,我只是想展示代码的主要结构。至于 AES 上的 DES 和 EBC 上的 CBC,我已经阅读了 DES 的弱点,只是不幸的是,我无法控制集成的 PHP 部分,而从事它的开发人员很可能会坚持使用 DES .那么,如果我使用我发布的 Java 代码但我更改为new SecretKeySpec(key.getBytes(), "DES");
和 Cipher.getInstance("DES/CBC/0");
,加密/解密是否兼容?
或者没有办法在 Java 中使用零填充,我必须在 PHP 代码中包含 PKCS5 填充?
太棒了,非常感谢拉兹。我会尽快尝试一下,我会告诉你这是怎么回事。以上是关于字符串加密 PHP/Java的主要内容,如果未能解决你的问题,请参考以下文章