brossquad/laravel-crypto

该包已被废弃,不再维护。作者建议使用codelieutenant/laravel-crypto包。

php(laravel)应用中常用的加密算法

v0.1.0 2020-08-07 12:47 UTC

This package is auto-updated.

Last update: 2024-02-27 20:15:31 UTC


README

常见哈希函数的包装类

Build Status GitHub issues GitHub stars GitHub license

介绍

许多网络应用程序都使用某种形式的加密,但大多数程序员不知道该使用哪种算法。

有很多选择,但其中大多数现在都很糟糕(看看MD4和MD5)。大多数好的函数都有非常复杂的API(如libsodium),所以我想要一个干净的“Laravel方式”和OOP对这些API的访问。我选择编写Laravel库(因为Laravel是最常用的PHP框架),以帮助程序员(特别是新手)在需要加密时。

这个库提供了易于使用的API的哈希和签名算法。

入门指南

安装

$ composer require brossquad/laravel-crypto

发布配置文件

php artisan vendor:publish --provider="BrosSquad\LaravelCrypto\HashingServiceProvider"

生成EdDSA私钥和公钥

Artisan命令将在PUBLIC_CRYPTO_PRIVATE_KEYPUBLIC_CRYPTO_PUBLIC_KEY环境变量(默认为storage_path('crypto_public|private.key'))中生成私钥和公钥。

$ php artisan crypto:keys

工具

编码

Base64编码

use BrosSquad\LaravelCrypto\Support\Base64;

$binaryData = random_bytes(32);

// STANDARD VERSION

// Standard encoding
$base64 = Base64::encode($binaryData);
 
// Url encoding
$base64 = Base64::urlEncode($binaryData);

// Standard decoding
$binary = Base64::decode($base64);

// Url decoding
$binary = Base64::urlDecode($base64);


// CONSTANT TIME ENCODING AND DECODING

// Standard encoding
$base64 = Base64::constantEncode($binaryData);

// Url encoding
$base64 = Base64::constantUrlEncode($binaryData);

// Url encoding with no padding (=)
$base64 = Base64::constantUrlEncodeNoPadding($binaryData);

// Standard decoding
$binary = Base64::constantDecode($base64);

// Url decoding
$binary = Base64::constantUrlDecode($base64);

// Url decoding with no padding
$binary = Base64::constantUrlDecodeNoPadding($base64);



// LENGTH CHECKING

// Get maximum length for the byte buffer from base64 encoded string 
$bufferLength = Base64::maxEncodedLengthToBytes($base64Length);

// Get exact length for byte buffer from base64 encoded
$bufferLength = Base64::encodedLengthToBytes($base64String);

// Get base64 string length from byte buffer length
$base64Length = Base64::encodedLength($bufferLength, $hasPadding);

生成随机数据

use BrosSquad\LaravelCrypto\Support\Random;

// Generate random string
$randomString = Random::string(60); // Generates random string base64 url encoded with no padding 

// Generate random bytes
$randomBytes = Random::bytes(32); // Generates buffer filled with crypto secure random bytes

// Generate random int
$randomImt = Random::int($min, $max);

通用哈希

Laravel加密库使用最新和最好的哈希算法。(Blake2b)

使用外观

namespace App\Services;

use BrosSquad\LaravelCrypto\Facades\Hashing;

class Service 
{
    public function hashing(): void
    {
        $data = 'Hello World';
        $blake2bHash = Hashing::hash($data); // Base64 Encoded string
        $blake2HashBinary = Hashing::hashRaw($data); // Binary Data, outputs 64 bytes of Blake2 hash
        // To check the length of binary strings use mb_strlen($binary, '8bit') function
    }
    
    public function checkingHash(): void
    {
        $hash1 = Hashing::hash('String 1');
        $hash2 = Hashing::hash('String 2');
        // Uses constant time compare to check 
        // if two hashes are equal
        // !! It supports binary data !!
        if(Hashing::equals($hash1, $hash2)) {
            // Hashes are equal
        }
    }

    public function hashVerification(): void {
        $data = 'Hello World';
        $hash = Hashing::hash($data);
        
        // !! Does not support binary hash !!
        // !! For binary data use verifyRaw !!
        if(Hashing::verify($hash,$data)) {
            // When data is hashed, hashes are same
        }
    }
}

使用依赖注入

当你使用依赖注入时,它将始终使用最佳算法。它消除了错误的空间;

namespace App\Services;

use \BrosSquad\LaravelCrypto\Contracts\Hashing;

class Service 
{
    protected Hashing $hashing;

    public function __construct(Hashing $hashing) 
    {
        $this->hashing = $hashing;        
    }

    public function hashing(): void
    {
        $data = 'Hello World';
        $blake2bHash = $this->hashing->hash($data); // Base64 Encoded string
        $blake2HashBinary = $this->hashing->hashRaw($data); // Binary Data, outputs 64 bytes of Blake2 hash
        // To check the length of binary strings use mb_strlen($binary, '8bit') function
    }
    
    public function checkingHash(): void
    {
        $hash1 = $this->hashing->hash('String 1');
        $hash2 = $this->hashing->hash('String 2');
        // Uses constant time compare to check 
        // if two hashes are equal
        // !! It supports binary data !!
        if($this->hashing->equals($hash1, $hash2)) {
            // Hashes are equal
        }
    }

    public function hashVerification(): void {
        $data = 'Hello World';
        $hash = $this->hashing->hash($data);
        
        // !! Does not support binary hash !!
        // !! For binary data use verifyRaw !!
        if($this->hashing->verify($hash,$data)) {
            // When data is hashed, hashes are same
        }
    }
}

尽可能使用默认哈希算法(BLAKE2B)。这是现在最安全的哈希,而且比行业目前使用的任何其他算法都要快(除了尚未在libsodium中实现的BLAKE3)。

默认哈希API是libsodium函数的包装。它提供了在Laravel项目中工作的良好API。

这些函数不应用于密码哈希。永远不要!!对于密码哈希,请使用Laravel默认的Hash外观或Hasher接口。

共享密钥签名

共享密钥签名使用SHA512/256 HMAC完成。(Sha512/256 -> SHA512针对X86_64架构进行了优化,这是现在大多数计算机和服务器运行的架构,但SHA512太长了,所以将其截断到256位(64字节),因此得名SHA512/256,提供与SHA512相同的安全性,但更短。)

更多信息请参阅HMAC

使用外观

namespace App\Service;

use BrosSquad\LaravelCrypto\Facades\Hmac;

class Service 
{
    public function createSignature()
    {
        $data = 'Hello World';

        $signature = Hmac::sign($data); // Base64 Encoded encoded signature

        $signature = Hmac::signRaw($data); // Raw bytes for signature
        
        // Rest of the code
    }

    public function verifySigunature(string $signature) 
    {
        $data = 'Hello World';
        
        if(Hmac::verify($data, $signature)) {
            // Signature is valid
        } else {
            // Signature is invalid
        }
    }
}

使用依赖注入

namespace App\Service;

use BrosSquad\LaravelCrypto\Contracts\Signing;

class Service 
{
    private Signing $hmac;

    public function __construct(Signing $hmac) 
    {
        $this->hmac = $hmac;
    }

    public function createSignature()
    {
        $data = 'Hello World';

        $signature = $this->hmac->sign($data); // Base64 Encoded encoded signature

        $signature = $this->hmac->signRaw($data); // Raw bytes for signature
        
        // Rest of the code
    }

    public function verifySigunature(string $signature) 
    {
        $data = 'Hello World';
        
        if($this->hmac->verify($data, $signature)) {
            // Signature is valid
        } else {
            // Signature is invalid
        }
    }
}

公钥签名

公钥签名使用公钥密码学的最新技术 -> EdDSA或Ed25519算法,由著名密码学家Daniel Bernstein开发。它基于Edwards曲线,比RSA(许多更安全)快得多。公钥和私钥都很短,这使得算法可以更快地运行。 whenever可以使用EdDSA算法进行公钥签名

在开始使用EdDSA之前,请使用Artisan控制台命令$ php artisan crypto:keys 生成私钥和公钥。

使用外观

namespace App\Service;

use BrosSquad\LaravelCrypto\Facades\EdDSA;

class Service 
{
    public function createSignature()
    {
        $data = 'Hello World';

        $signature = EdDSA::sign($data); // Base64 Encoded encoded signature

        $signature = EdDSA::signRaw($data); // Raw bytes for signature
        
        // Rest of the code
    }

    public function verifySigunature(string $signature) 
    {
        $data = 'Hello World';
        
        if(EdDSA::verify($data, $signature)) {
            // Signature is valid
        } else {
            // Signature is invalid
        }
    }
}

使用依赖注入

namespace App\Service;

use BrosSquad\LaravelCrypto\Contracts\PublicKeySigning;

class Service 
{
    private PublicKeySigning $signing;

    public function __construct(PublicKeySigning $signing) 
    {
        $this->signing = $signing;
    }

    public function createSignature()
    {
        $data = 'Hello World';

        $signature = $this->signing->sign($data); // Base64 Encoded encoded signature

        $signature = $this->hmac->signRaw($data); // Raw bytes for signature
        
        // Rest of the code
    }

    public function verifySigunature(string $signature) 
    {
        $data = 'Hello World';
        
        if($this->hmac->verify($data, $signature)) {
            // Signature is valid
        } else {
            // Signature is invalid
        }
    }
}

高级

加密

LaravelCrypto库提供了2个额外的加密算法。它使用默认的Laravel Encrypter接口和密钥,因此不需要对代码进行任何更改,除了配置文件。

仅在新应用程序中使用此功能。

在旧应用程序中使用

如果你有一个使用Laravel默认加密的应用程序,并且你在数据库中存储了加密数据,你需要使用新算法重新加密这些数据!

// app.cofig
return [
    // ...
    
    // XChaCha20Poly1305 Algorithm
    'cipher' => 'XChaCha20Poly1305',
    
    // AES 256 GCM
    //!! Make sure you have hardware acceleration for
    //  AES-256-GCM, it wont work if your sever does not support it !!
    'cipher' => 'AES-256-GCM',

    // .. 
]

基准测试

加密
主题 描述 修订版本 迭代次数 内存峰值 最佳时间 平均时间 最差时间
benchLaravelEncryption 默认Laravel加密器(AES-256-CBC) 100 10 2,259,976b 952.012μs 957.365μs 974.771μs
benchXChaCha20Poly1305 XChaCha20Poly1305加密 100 10 2,458,008b 265.780μs 267.313μs 270.197μs
benchAes256gcm AES 256 GCM加密 100 10 2,457,984b 252.650μs 254.105μs 256.572μs
解密
主题 描述 修订版本 迭代次数 内存峰值 最佳时间 平均时间 最差时间
benchLaravelDecryption 默认Laravel解密器(AES-256-CBC) 100 10 2,508,208b 1,661.467μs 1,666.177μs 1,677.097μs
benchXChaCha20Poly1305Decryption XChaCha20Poly1305解密 100 10 2,529,600b 455.560μs 458.140μs 465.492μs
benchAes256gcmDecryption AES 256 GCM解密 100 10 2,529,576b 447.280μs 449.552μs 453.438μs

SHA256

使用哈希外观

使用依赖注入

SHA512

使用哈希外观

使用依赖注入