1

是否可以指定 PHPMailer 中使用的加密协议版本?

尝试构建一个用于测试 SMTP 配置的小型 Web 工具。我曾经能够在 .NET 中指定协议版本,但现在我使用的是 apache,我正在尝试使用 phpmailer 在 PHP 页面中执行此操作。所以我需要让它只尝试一个单一的加密版本,比如 TLS 1.3。

我知道我可以将 smtpautoTLS 设置为 FALSE。但是我可以在 SMTPOptions 数组中指定 TLS 1.3 或 SSL v3 吗?我似乎无法在文档/示例/谷歌中找到它。

谢谢!

编辑更新代码并确认此代码仅适用于 SMTPS/隐式样式,但不适用于 STARTTLS

<?php
    require_once 'PHPMailer/vendor/autoload.php';
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\Exception;
    
    $from = $_POST['from'];
    $to = $_POST['to'];
    $subj = $_POST['subj'];
    $body = $_POST['body'];
    $server = $_POST['addr'];
    $port = $_POST['port'];
    $auth = $_POST['auth'];
    $enctype = $_POST['enctype'];
    $encver = $_POST['encver'];
    $authuser = $_POST['authuser'];
    $authpw = $_POST['authpw'];
    
    $mail = new PHPMailer(true);
    $mail->IsSMTP();
    //$mail->SMTPDebug = 2; //2 for debugging with server responses. 0-4 as choices
    
    $smtpopts = array();
    
    if($encver == "auto")
    {
        $mail->SMTPAutoTLS = true;
    }
    else
    {
        $mail->SMTPAutoTLS = false;
    }
    
    if($auth == 1)
    {
        $mail->SMTPAuth = true;
        $mail->Username = $authuser;
        $mail->Password = $authpw;
        
        switch($enctype)
        {
            case "implicit":
                $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
                break;
            case "explicit":
                $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
                break;
        }
        
        switch($encver)
        {
            case "ssl3_0":
                $smtpopts['ssl'] = array('crypto_method'  => STREAM_CRYPTO_METHOD_SSLv3_CLIENT);
                break;
            
            case "tls1_0":
                $smtpopts['ssl'] = array('crypto_method'  => STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT);
                break;
            
            case "tls1_1":
                $smtpopts['ssl'] = array('crypto_method'  => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT);
                break;
                
            case "tls1_2":
                $smtpopts['ssl'] = array('crypto_method'  => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT);
                break;
            
            case "tls1_3":
                $smtpopts['ssl'] = array('crypto_method'  => STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT);
                break;
        }
    
        $mail->SMTPOptions = $smtpopts;
    }
    else
    {
        $mail->SMTPAuth = false;
    }
    
    $mail->Host = $server;
    $mail->Port = $port;
    
    $mail->SetFrom($from);
    $mail->AddAddress($to);
    $mail->Subject = $subj;
    $mail->MsgHTML($body);
    
    $response = array();
    
    try
    {
        header('Content-Type: application/json');
        $mail->Send();
        $response['success'] = 1;
        $response['msg'] = "Success";
        echo json_encode($response);
    }
    catch (Exception $e)
    {
        $response['success'] = 0;
        $response['msg'] = $e->errorMessage();
        error_log($e->errorMessage());
        echo json_encode($response);
    }
    catch (\Exception $e)
    {
        $response['success'] = -99;
        $response['msg'] = $e->getMessage();
        error_log($e->getMessage());
        echo json_encode($response);
    }
?>
4

1 回答 1

0

TLSv1.3 支持的关键常量是STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT,它是在 PHP 7.4.0 中引入的,但似乎没有记录。

STREAM_CRYPTO_METHOD_TLS_CLIENT 当通过 STARTTLS 初始化加密时, PHPMailer 使用 SMTP 类中的 TLS 常量。如您在 PHP 源代码中所见,此常量结合了 TLS 1.0、1.1、1.2 和 1.3 。

因此,对于您的特定情况,您希望将STREAM_CRYPTO_METHOD_TLS_CLIENT默认值替换为STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT. 您可以通过子类化 SMTP 类并覆盖该方法来实现您的要求(至少出于测试目的),startTLS以便您可以控制 TLS 常量。

但是,该方法仅适用于 SMTP+STARTTLS,不适用于 SMTPS。对于 SMTPS(sslPHPMailer 中的模式),您可以使用对两者都适用的不同方法。查看这个测试用例表明您可以在传递给的选项中指定连接类型常量stream_context_create——这与 PHPMailer 允许您访问的数组完全相同,所以试试这个:

$mail->SMTPOptions = [
    'ssl' => ['crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT]
];
于 2020-08-03T17:17:41.887 回答