用 PHP 加密消息,用 JavaScript 解密

Posted

技术标签:

【中文标题】用 PHP 加密消息,用 JavaScript 解密【英文标题】:Encrypt message in PHP, decrypt in JavaScript 【发布时间】:2012-01-17 09:11:17 【问题描述】:

我想通过 php 加密消息,但在客户端,我希望 javascript 解密它。我曾尝试过 Blowfish(使用 mcrypt ),但我发现 php 回显非字母数字字符和 Javascript 显示字母数字。我正在使用 ajax,因此页面不会重新加载。

我测试了来自http://aam.ugpl.de/?q=node/1060 和http://www.php-einfach.de/blowfish_en.php#ausgabe 的代码。

感谢任何帮助。

编辑:我使用 Diffie-Hellman 来计算随机生成的数字 a 和 b 的密钥。下面是php代码的结果

class Encryption

const CYPHER = 'blowfish';
const MODE   = 'cbc';
const KEY    = '26854571066639171754759502724211797107457520821';

public function encrypt($plaintext)

    $td = mcrypt_module_open(self::CYPHER, '', self::MODE, '');
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    mcrypt_generic_init($td, self::KEY, $iv);
    $crypttext = mcrypt_generic($td, $plaintext);
    mcrypt_generic_deinit($td);
    return $iv.$crypttext;


public function decrypt($crypttext)

    $plaintext = '';
    $td        = mcrypt_module_open(self::CYPHER, '', self::MODE, '');
    $ivsize    = mcrypt_enc_get_iv_size($td);
    $iv        = substr($crypttext, 0, $ivsize);
    $crypttext = substr($crypttext, $ivsize);
    if ($iv)
    
        mcrypt_generic_init($td, self::KEY, $iv);
        $plaintext = mdecrypt_generic($td, $crypttext);
    
    return $plaintext;



$encrypted_string = Encryption::encrypt('this is a test');
$decrypted_string = Encryption::decrypt($encrypted_string);

echo "encrypted: $encrypted_string<br>";
echo "decrypted: $decrypted_string<br>";

encrypted: µ˜?r_¿ÖŸŒúw‰1‹Žn!úaH 
decrypted: this is a test

【问题讨论】:

为什么需要这样做?如果是为了传输安全,您必须使用 HTTPS,否则您会通过同一条线路传输密钥,这样攻击者就可以轻松解密您的数据。如果您想阻止用户查看数据,例如with Firebug:如果有人想看,他会的。 这个有什么用?任何人都可以获取用于解密它的密钥。 OP 没有说他/她将通过网络传输密钥。如果它以其他方式分发,例如在用户注册后通过电子邮件分发,这可能会起作用,尽管它肯定不是 100% 安全... 其实我没有转移密钥,我使用 Diffie-Hellman 获取密钥 【参考方案1】:

这个来自斯坦福大学学生的 javascript AES 加密库是我见过的最好的:

http://crypto.stanford.edu/sjcl/

但请注意他们的警告:

我们相信 SJCL 提供了 Javascript 中实际可用的最佳安全性。 (不幸的是,这没有桌面应用程序那么好,因为要完全防止代码注入、恶意服务器和侧通道攻击是不可行的。)

更新:

在 PHP 中,加密后使用base64_encode(),解密前使用base64_decode()。这样,它将以可安全传输的字符呈现。在浏览器中,使用atob()btoa()

【讨论】:

很好的链接,谢谢。但是在服务器端,PHP 正在回显奇怪的符号,我认为 javascript 无法使用 SJCL 对其进行解密。 如果您的问题与 PHP 有关,您需要发布相关代码,以便我们查看该符号是什么以及可以做些什么来帮助您... 很抱歉回复晚了,直到现在我真的有事要做。我发布服务器端的代码 我按你说的试过了,但没有运气。在用 Javascript 解密之前使用 atob() 只是让 Javascript 解密原始的非字母数字字符。在aam.ugpl.de/?q=node/1060,加密“这是一个测试”,带有密码“给出”AD5FB4954211797107457520821“给出了”AD5FB495D6DF5865858B784CE198E51F“,如果我是正确的,但Mcrypt给出”μ〜?r_¿öÿœúw‰1 发布客户端javascript解密代码,因为我无法真正理解该链接,因为它似乎是德语。 base64 编码(在服务器上)只是为了让您可以通过网络安全地传输数据。在 JS 中,您然后在解密之前取消编码。您的问题可能与您的解密方式有关。在 JS 中解密时是否使用所有相同的参数?

以上是关于用 PHP 加密消息,用 JavaScript 解密的主要内容,如果未能解决你的问题,请参考以下文章

php中的AES加密,然后用Javascript(cryptojs)解密

有关MD5与PHP,高手进

加密的zip文件,在PHP 7.2之前

JavaScript 和 PHP 中不同的 AES 加密

如何在php中加密/解密数据?

用c#做aes加密 为啥在线解密解不了