简体   繁体   English

PHP:使用证明密钥验证 web 的请求是否来自 Office

[英]PHP: Verifying that requests originate from Office for the web by using proof keys

I'm trying to Verifying that requests originate from Office for the web by using proof keys我正在尝试 使用证明密钥验证 web 的请求是否来自 Office

I have read this resource many times but still do not know how to implement it in PHP.我已多次阅读此资源,但仍然不知道如何在 PHP 中实现它。

I tried the code below it didn't seem to solve the problem, I do not know what to do next.我试过下面的代码似乎没有解决问题,我不知道下一步该怎么做。

Can someone give me a suggestion?有人可以给我一个建议吗?

$rsa = new Crypt_RSA();
$modulus = new Math_BigInteger(base64_decode($modulus), 256);
$exponent = new Math_BigInteger(base64_decode($exponent), 256);

$rsa->loadKey(array('n' => $modulus, 'e' => $exponent));
$rsa->setPublicKey();
$publicKey = $rsa->getPublicKey();

I understand that verifying WOPI proof key is quite complicated to implement while extracting programming logic from their explanation in the document is challenging.我知道验证 WOPI 证明密钥实现起来相当复杂,而从文档中的解释中提取编程逻辑具有挑战性。 Unfortunately, I'm not a PHP developer.不幸的是,我不是 PHP 开发人员。 However, I'd like to share my production C# code in case it could help.但是,我想分享我的生产 C# 代码以防万一。

private async Task<bool> ValidateWopiProof(HttpContext context)
{
    // Make sure the request has the correct headers
    if (!context.Request.Headers.ContainsKey(WopiRequestHeader.PROOF) ||
        !context.Request.Headers.ContainsKey(WopiRequestHeader.TIME_STAMP))
        return false;

    // TimestampOlderThan20Min
    var timeStamp = long.Parse(context.Request.Headers[WopiRequestHeader.TIME_STAMP].ToString());
    var timeStampDateTime = new DateTime(timeStamp, DateTimeKind.Utc);
    if ((DateTime.UtcNow - timeStampDateTime).TotalMinutes > 20)
        return false;

    // Set the requested proof values
    var requestProof = context.Request.Headers[WopiRequestHeader.PROOF];
    var requestProofOld = String.Empty;
    if (context.Request.Headers.ContainsKey(WopiRequestHeader.PROOF_OLD))
        requestProofOld = context.Request.Headers[WopiRequestHeader.PROOF_OLD];

    // Get the WOPI proof info from Wopi discovery
    var wopiProofPublicKey = await _wopiDiscovery.GetWopiProof();

    // Encode the values into bytes
    var accessTokenBytes = Encoding.UTF8.GetBytes(context.Request.Query["access_token"].ToString());

    var hostUrl = GetAbsolouteUrl(context);
    var hostUrlBytes = Encoding.UTF8.GetBytes(hostUrl.ToUpperInvariant());

    var timeStampBytes = BitConverter.GetBytes(Convert.ToInt64(context.Request.Headers[WopiRequestHeader.TIME_STAMP])).Reverse().ToArray();

    // Build expected proof
    List<byte> expected = new List<byte>(
        4 + accessTokenBytes.Length +
        4 + hostUrlBytes.Length +
        4 + timeStampBytes.Length);

    // Add the values to the expected variable
    expected.AddRange(BitConverter.GetBytes(accessTokenBytes.Length).Reverse().ToArray());
    expected.AddRange(accessTokenBytes);
    expected.AddRange(BitConverter.GetBytes(hostUrlBytes.Length).Reverse().ToArray());
    expected.AddRange(hostUrlBytes);
    expected.AddRange(BitConverter.GetBytes(timeStampBytes.Length).Reverse().ToArray());
    expected.AddRange(timeStampBytes);
    byte[] expectedBytes = expected.ToArray();

    return (VerifyProofKeys(expectedBytes, requestProof, wopiProofPublicKey.Value) ||
        VerifyProofKeys(expectedBytes, requestProofOld, wopiProofPublicKey.Value) ||
        VerifyProofKeys(expectedBytes, requestProof, wopiProofPublicKey.OldValue));
}

private string GetAbsolouteUrl(HttpContext context)
{
    var url = $"{_wopiUrlService.ApiAddress.TrimEnd('/')}{context.Request.Path}{context.Request.QueryString}";
    return url.Replace(":44300", "").Replace(":443", "");
}

private bool VerifyProofKeys(byte[] expectedProof, string proofFromRequest, string discoPublicKey)
{
    using (RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider())
    {
        try
        {
            rsaProvider.ImportCspBlob(Convert.FromBase64String(discoPublicKey));
            return rsaProvider.VerifyData(expectedProof, "SHA256", Convert.FromBase64String(proofFromRequest));
        }
        catch (FormatException)
        {
            return false;
        }
        catch (CryptographicException)
        {
            return false;
        }
    }
}

This implementation follows the document spec.此实现遵循 文档规范。 For the method _wopiDiscovery.GetWopiProof() , I just get proof-key section from Wopi Discovery .对于_wopiDiscovery.GetWopiProof()方法,我只是从Wopi Discovery获得proof-key部分。

在 wopi 发现中获取 wopi 证明密钥 . .

@Rachanee is your solution working? @Rachanee 您的解决方案有效吗? I have the same code but validation is failing.我有相同的代码,但验证失败。

You can find a WOPI Proof Validator in PHP, in this package: https://github.com/Champs-Libres/wopi-lib/您可以在 PHP 中找到 WOPI 证明验证器,在此 package: https://github.com/Champs-Libres/wopi

This package is a helper for integrating WOPI protocol in PHP applications.此 package 是在 PHP 应用程序中集成 WOPI 协议的助手。

It contains a WOPI Proof Validator service that you can use out of the box.它包含一个开箱即用的 WOPI 证明验证器服务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM