对称加密为什么要使用消息认证码 (MAC) 签名

来源

PHP 文档看到用 openssl_encrypt() 实现 AES 对称加密算法

// PHP 5.6+ 的 AES 认证加密例子
//$key previously generated safely, ie: openssl_random_pseudo_bytes
$plaintext = "message to be encrypted";
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
$ciphertext = base64_encode( $iv.$hmac.$ciphertext_raw );

//decrypt later....
$c = base64_decode($ciphertext);
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = substr($c, 0, $ivlen);
$hmac = substr($c, $ivlen, $sha2len=32);
$ciphertext_raw = substr($c, $ivlen+$sha2len);
$original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
$calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
if (hash_equals($hmac, $calcmac))// timing attack safe comparison
{
    echo $original_plaintext."\n";
}

疑惑

为什么要进行 mac 校验呢?我有几点疑惑:

  1. 是防止他人传入一个伪造的 code,通过 decrypt 的结果可以推算出密钥($key)吗?
  2. 不使用 mac 校验的情况,有可能伪造成功一个加密后的值并能openssl_decrypt()成功吗?
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
最佳答案

是防止他人传入一个伪造的 code,通过 decrypt 的结果可以推算出密钥 ($key) 吗?

不是

不使用 mac 校验的情况,有可能伪造成功一个加密后的值并能 openssl_decrypt() 成功吗? 不能

目的:

第一:防篡改 基于加密原理那一套的理由是:保证消息在传输过程中没有被篡改。

第二:防重放 加密后的密文的hmac具有唯一性,短时间内相同hash的密文第二次被投递,可以根据该hash直接判定为重放攻击拒绝处理。

1年前 评论
fansheng (楼主) 1年前
讨论数量: 2

是防止他人传入一个伪造的 code,通过 decrypt 的结果可以推算出密钥 ($key) 吗?

不是

不使用 mac 校验的情况,有可能伪造成功一个加密后的值并能 openssl_decrypt() 成功吗? 不能

目的:

第一:防篡改 基于加密原理那一套的理由是:保证消息在传输过程中没有被篡改。

第二:防重放 加密后的密文的hmac具有唯一性,短时间内相同hash的密文第二次被投递,可以根据该hash直接判定为重放攻击拒绝处理。

1年前 评论
fansheng (楼主) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!