komputerwiz/secure-token

加密安全的令牌

1.1.1 2018-01-29 16:26 UTC

This package is not auto-updated.

Last update: 2024-09-14 18:09:43 UTC


README

加密敏感数据,并将生成的密文用作应用程序的备忘录。

在用户导入或生成、电子邮件验证和/或丢失凭据的情况下,通常发送一封包含临时链接的电子邮件,链接指向一个页面,目标用户可以在该页面上重置其密码。有时此类交易的状态(生成的随机数、请求过期等)存储在服务器数据库中的用户账户上。这需要额外的维护。相反,相关的交易信息可以外部化到令牌中。如果操作不当,拦截和篡改令牌可能会使攻击者获得不需要的账户访问权限。此库提供的解决方案通过令牌外部化状态提供了一种加密安全的方法:数据被加密以确保机密性,然后被签名以确保完整性。

安装

将以下内容添加到您的 composer.json

require: {
    "komputerwiz/secure-token": "dev-master"
}

用法

可用的加密方法包括

  • AES 256 在 CBC 模式下使用 SHA-512 HMAC 签名 (Komputerwiz\Security\Token\SecureToken\Aes256CbcSha512SecureToken)
  • AES 256 在 CBC 模式下使用 SHA-256 HMAC 签名 (Komputerwiz\Security\Token\SecureToken\Aes256CbcSha256SecureToken)

随着 PHP 加密技术的改进,我将尝试实现更多(例如,一旦支持AES 256 GCM)。您也可以自由实现自己的,并提交拉取请求!

可用的装饰器

  • Komputerwiz\Security\Token\SecureToken\ExpiringSecureToken - 令牌在设置的时间间隔后失效(并在解码时触发 TokenException
  • Komputerwiz\Security\Token\SecureToken\TimestampedSecureToken - 记录令牌签发的时间戳。使用 getTimestamp($token) 实例方法检索此时间戳。
<?php

use Komputerwiz\Security\Token\SecureToken\Aes256CbcSha256SecureToken;
use Komputerwiz\Security\Token\SecureToken\ExpiringSecureToken;
use Komputerwiz\Security\Token\SecureToken\TimestampedSecureToken;
use Komputerwiz\Security\Token\SecureToken\TokenException;

// helper PBKDF2 method for deriving a key from a secret; not required, but recommended
$encryptionKey = Aes256CbcSha256SecureToken::pbkdf2('secret', 'salt', 10000);
$signingKey = Aes256CbcSha256SecureToken::pbkdf2('secret', 'salt', 10000);

// if only one key is provided, that key will be used for both encrypting and signing
$token = new Aes256CbcSha256SecureToken($encryptionKey, $signingKey);


// optionally wrap it in an ExpiringSecureToken so that it will not be accepted after a set interval
$token = new ExpiringSecureToken($token, new \DateInterval('P1D'));

// record issue dates of tokens
$token = new TimestampedSecureToken($token);


$data = 'set your super secret data here';
$binaryToken = $token->encode($data)

// Do something with the $binaryToken. If it needs to be printed in ASCII text,
// be sure to base64_encode it and base64_decode it before the next step!


try {
    $data = $token->decode($binaryToken);
} catch (TokenException $e) {
    // token was either tampered with or expired
}


// get token creation timestamp (if $token instanceof TimestampedSecureToken)
$issued = $token->getTimestamp($binaryToken);

实现您自己的 SecureToken

有两种方法可以实现您自己的 SecureToken 编码器

实现 Komputerwiz\Security\Token\SecureToken\SecureTokenInterface

这种方法给了您最大的自由去做您想做的事情,但保证安全则取决于您。这可能更适合实现一个委托给现有 SecureToken 实现的装饰器。

<?php

use Komputerwiz\Security\Token\SecureToken\SecureTokenInterface;

class MySecureTokenDecorator implements SecureTokenInterface
{
    /**
     * @var SecureTokenInterface $token
     */
    private $token;
    
    
    public function __construct(SecureTokenInterface $token)
    {
        $this->token = $token;
    }
    
    /**
     * {@inheritDoc}
     */
    public function encode($data)
    {
        // do something with $data to suit your needs (e.g. adding a header)
        
        return $this->token->encode($data);
    }
    
    /**
     * {@inheritDoc}
     */
    public function decode($token)
    {
        $data = $this->token->decode($token);
        
        // perform additional validity checks and/or modify $data
        
        return $data;
    }
}

扩展 Komputerwiz\Security\Token\SecureToken\SecureToken

这种方法遵循了众所周知的加密和签名范例。它负责生成输入向量,并调用您自己实现的加密、解密和签名方法。

<?php

use Komputerwiz\Security\Token\SecureToken\SecureToken;

class MySecureToken extends SecureToken
{
    /**
     * {@inheritDoc}
     */
    protected function getInitializationVectorLength()
    {
        // calculate input vector size (usually block size of algorithm)
        // @see openssl_cipher_iv_length($cipher)
        return $length;
    }

    /**
     * {@inheritDoc}
     */
    protected function sign($payload)
    {
        // generate signature for $payload
        return $signature;
    }

    /**
     * {@inheritDoc}
     */
    protected function encrypt($iv, $plaintext)
    {
        // encrypt $plaintext using init. vector $iv if necessary
        return $encrypted;
    }

    /**
     * {@inheritDoc}
     */
    protected function decrypt($iv, $ciphertext)
    {
        // decrypt $ciphertext using init. vector $iv if necessary
        return $decrypted;
    }
}

许可

版权 2015 Matthew Barry

根据 Apache 许可证 2.0 版(“许可证”);除非适用法律要求或经书面同意,否则您不得使用此文件,除非遵守许可证。您可以在以下位置获得许可证副本:

https://apache.ac.cn/licenses/LICENSE-2.0

除非适用法律要求或书面同意,否则在许可证下分发的软件按“原样”提供,不提供任何明示或暗示的保证或条件。有关许可证的具体语言管理许可和限制,请参阅许可证。