1

我正在设计一个允许最终用户从他们的浏览器中进行测验的应用程序。部分要求是,当测验开始时间临近时,问题应立即显示给每个参与者。这使得从服务器向最终用户提供问题不太合理,因为这会导致请求突然爆发,因此我打算在他们连接后立即向他们提供问题,并且距离测验开始时间不到 2 小时。问题是,由于这是一场比赛,所以在开始时间之前不应该看到问题,因此需要对其进行加密。

我决定分两个阶段进行加密,第一阶段加密使用非对称 RSA 加密来交换我已经成功完成的密钥交换。此密钥将用于加密将在服务器和客户端之间发送的任何其他数据。

现在的问题是对称加密部分。我正在尝试使用 openssl_encrypt 方法在服务器端进行加密,并尝试在客户端使用 pidcrypt(一个 javascript 加密/解密库)进行解密。原来 pidcrypt 要求您的 iv (初始化向量)长度为 8 个字节,但是使用 AES-256-CBC 模式的 openssl_encrypt 不允许使用 8 个字节,而是一直坚持使用 16 个字节。我做了很多排列和实验,但没有运气。在 pidcrypt 的文档中说明它与 openssl 兼容,所以我的问题是 - 我做错了什么?下面是使用 PHP 在服务器端加密的代码

        $iv_len = openssl_cipher_iv_length("AES-256-CBC");
            $key='My very secret key.......';
    $iv = openssl_random_pseudo_bytes($iv_len);
    $enc = openssl_encrypt('Hello', "AES-256-CBC", $key, 0, $iv);
    $encryptedMessage = base64_encode("Salted__".bin2hex($iv).$enc);
    echo json_encode(array('key'=>$key, 'encrypt'=>$encryptedMessage,));

请问有没有办法让 $iv_len 长 8 字节,而不是这段代码不断返回的 16 字节,我是否以正确的方式接近整个设置。谢谢

4

1 回答 1

0

pidcrypt不使用 8 字节 IV,它使用 8 字节盐。IV 和盐是不同的概念,尽管它们有许多相似之处。

pidcrypt随机化的 salt 中,与密码和 MD5 一起使用来生成密钥和 IV。然后将盐预先添加到密文中(就像 openssl 一样)。服务器应该使用相同的方法来生成密钥和 IV,使用预先添加的盐值和共享密码。目前您正在尝试直接使用密钥和 IV,这是不正确的。

无论库是什么,用于解密任何 CBC 模式的 IV 都应该与底层密码的块大小相同。这里的底层分组密码是 AES,这意味着 IV 将始终为 16 个字节。

您应该仔细阅读用户对未记录openssl_encrypt方法的评论,然后可能在 PHP 中找到另一个与 openssl 兼容的库,或者找到/实现OpenSSL 密钥派生方法 ( EVP_BytesToKey)

请注意,openssl命令行实用程序会生成以下输出:

00000000  53 61 6c 74 65 64 5f 5f  44 a2 2f ee ac ee 94 fd  |Salted__D./.....|
00000010  6f 93 17 24 44 12 88 66  e7 fe 5c d5 7d 81 fe d9  |o..$D..f..\.}...|
00000020

所以这是一个 ASCII 字符串,Salted__后跟一个 8 字节的随机盐(不是 IV),然后是 16 个字节的密文(一个完整的块)。

于 2013-08-07T20:58:13.850 回答