关于php:PHP的opensslencrypt的补充说明

在PHP(PHP 5 >= 5.3.0, PHP 7, PHP 8)中,openssl_encrypt的参数大抵如下:

openssl_encrypt(
    string $data,
    string $cipher_algo,
    string $passphrase,
    int $options = 0,
    string $iv = "",
    string &$tag = null,
    string $aad = "",
    int $tag_length = 16
): string|false

其中$data待加密的数据字符串,这很好了解,这里不做过多阐释。

  • $cipher_algo为加密算法,如AES-128-ECB,两头这个数字示意密钥长度为128位。所有加密算法可通过openssl_get_cipher_methods取得。
  • $passphrase为密钥。既然下面的算法都规定了密钥长度,那这个密钥的字符串长度就曾经确定下来了。但PHP随性的一点是如果密钥小于或超过算法指定的长度,也都能失常返回加密后果,而不像Java等语言间接抛出密钥长度不正确的异样。依据手册解释:

    若 passphrase 比预期长度短,将静默用 NUL 填充; 若比预期长度更长,将静默截断。

    那么NUL在PHP中体现又是什么?查了PHP源代码下的openssl实现,找到如下代码:

    if (key_len > password_len) {
      if ((OPENSSL_DONT_ZERO_PAD_KEY & options) && !EVP_CIPHER_CTX_set_key_length(cipher_ctx, password_len)) {
          php_openssl_store_errors();
          php_error_docref(NULL, E_WARNING, "Key length cannot be set for the cipher algorithm");
          return FAILURE;
      }
      key = emalloc(key_len);
      memset(key, 0, key_len); 
      memcpy(key, *ppassword, password_len);
      *ppassword = (char *) key;
      *ppassword_len = key_len;
      *free_password = 1;
    }

    memset(key, 0, key_len); 应该对应的就是ASCII中的零,也就是PHP里的chr(0)。所以如果一个密钥长度不够,PHP会主动在密钥前面用chr(0)有余。例如:AES-128-ECB算法,密钥长度应为128位,也就是字符串长度为16。这时如果密钥为”1234567890abcde”和”1234567890abcde”.chr(0)的意义是一样的,失去的加密后果也是一样的。至于超出长度主动截断,这应该很好了解了。

  • $options 是以下标记的按位或: OPENSSL_RAW_DATA 、 OPENSSL_ZERO_PADDING, 指定对于数据,如何填充的。
    其中OPENSSL_RAW_DATA的默认行为是PKCS7Padding

【腾讯云】轻量 2核2G4M,首年65元

阿里云限时活动-云数据库 RDS MySQL  1核2G配置 1.88/月 速抢

本文由乐趣区整理发布,转载请注明出处,谢谢。

您可能还喜欢...

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据