浅谈Laravel中如何对大文件进行加密

我已经搜索过用于解决此问题的软件包或解决方案,并遇到了这个 Stack Overflow 回答和这个 PHP 解决方案,该解决方案基本上是 Stack Overflow 所描述的解决方案的 PHP 实现。

我决定创建一个为 Laravel 设计的扩展包,使用简单,优雅的语法提供简单的文件加密 / 解密功能。

在这个教程中,我会详细描述加密大文件需要的所有步骤。

首先, 使用 Laravel 安装器创建一个新的 Laravel 项目, 命名为security-app:

laravel new security-app

在撰写本教程时,我正在使用 Laravel v6.5.2。

因为我们已经使用了 Laravel 安装程序,所以我们已经生成了一个应用程序密钥并将其添加到我们的 .env 文件中。 如果您使用其他安装方法,请不要忘记使用以下方法生成新的应用程序密钥:

php artisan key:generate

因为我们正在使用 Laravel Valet,所以应该已经为我们创建了 security-app.test 域名。 如果使用其他开发环境,则应添加一个本地域名指向新项目。

由于自 Laravel 6 以来前端脚手架已被移至 Laravel UI 中,因此我们将安装 laravel/ui 扩展包。

composer require laravel/ui — dev

接下来,我们将安装bootstrap和auth脚手架:

php artisan ui bootstrap --auth

并编译所有内容:

npm install && npm run dev

我们还需要在 .env 文件中配置数据库访问凭据并运行初始迁移:

php artisan migrate

现在,我们可以创建一个新用户并登录查看用户仪表板。

注意:在本演示中,我们将创建一个基本的上传表单,但是在您的应用程序中,您应该考虑使用更复杂的上传功能,对大文件使用分块上传。

您可以使用一个非常好的扩展包是 pion/laravel-chunk-upload.

Laravel Auth 脚手架为我们创建了一个 /home 路由,一个 HomeController 和一个 home.blade.php 视图文件。

让我们编辑 home.blade.php 文件并添加一个表单和一个上传字段:

<form action="{{ route('uploadFile') }}" method="post" enctype="multipart/form-data" class="my-4">
    @csrf

    <div class="form-group">
        <div class="custom-file">
            <input type="file" class="custom-file-input" id="userFile" name="userFile">
            <label class="custom-file-label" for="userFile">Choose a file</label>
        </div>
    </div>

    <button type="submit" class="btn btn-primary">Upload</button>

    @if (session()->has('message'))
        <div class="alert alert-success mt-3">
            {{ session('message') }}
        </div>
    @endif
</form>

然后添加相应的路由:

Route::post(‘/home', ‘HomeController@store')->name(‘uploadFile');

在 HomeController 中新增 store 方法。 此方法会将上传的文件存储在具有当前用户 ID 的文件目录中 (storage/app/files/{user-id}) 。

注意:这是不正确的做法,不应在生产环境中使用。 为了使本教程更加小巧,我们使用文件系统来获取用户的文件,但是在生产环境中,需要使用数据库来跟踪每个用户上传的文件。

<?php
   /**
     * Store a user uploaded file
     *
     * @param  \Illuminate\Http\Request $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        if ($request->hasFile('userFile') && $request->file('userFile')->isValid()) {
            Storage::putFile('files/' . auth()->user()->id, $request->file('userFile'));
        }

        return redirect()->route('home')->with('message', 'Upload complete');
    }

到了加密用户上传文件的阶段。我们将安装file-vault扩展包:

composer require soarecostin/file-vault

该软件包允许访问 FileVault 门面, 其中提供了一些用于加密和解密文件的方法,还提供了一些方法来设置选项,例如为每个文件设置不同的加密密钥,或指定该文件的 Laravel 文件系统磁盘。

我们将使用 FileVault::encrypt($file) 方法来加密用户上传的文件。 此功能将删除原始的未加密文件,并将其替换为具有相同名称和附加 .enc 扩展名的文件。

如果您想使用不同的名称命名文件,则可以将所需的名称作为第二个参数传递给 encrypt 方法。 如果您想保留原始文件,可以使用 encryptCopy 方法。

这就是我们的 store 方法现在的样子:

<?php
    /**
     * Store a user uploaded file
     *
     * @param  \Illuminate\Http\Request $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        if ($request->hasFile('userFile') && $request->file('userFile')->isValid()) {
            $filename = Storage::putFile('files/' . auth()->user()->id, $request->file('userFile'));

            // Check to see if we have a valid file uploaded
            if ($filename) {
                FileVault::encrypt($filename);
            }
        }

        return redirect()->route('home')->with('message', 'Upload complete');
    }

接下来,我们需要查看所有用户上传的文件,还需要一种下载它们的方法。

我们将在 HomeController 中创建一个新的 downloadFile 路由和一个新的 downloadFile 方法:

Route::get(‘/files/{filename}', ‘HomeController@downloadFile')->name(‘downloadFile');
<?php
    /**
     * Download a file
     *
     * @param  string  $filename
     * @return \Illuminate\Http\Response
     */
    public function downloadFile($filename)
    {
        // Basic validation to check if the file exists and is in the user directory
        if (!Storage::has('files/' . auth()->user()->id . '/' . $filename)) {
            abort(404);
        }

        return response()->streamDownload(function () use ($filename) {
            FileVault::streamDecrypt('files/' . auth()->user()->id . '/' . $filename);
        }, Str::replaceLast('.enc', '', $filename));
    }

downloadFile 使用 Laravel 原生的 streamDownload response, 接收一个回调.

在回调中,我们正在调用扩展包 FileVault 提供的 streamDecrypt 方法,它将对文件进行解密并将其逐段提供给streamDownload方法,从而允许您的用户直接下载解密文件。

现在,我们需要在上传表单下方显示所有用户的文件。 为此,我们将 $files 变量从 HomeController 的 index 方法发送到 home.blade.php 视图文件,并在上传表格的下面显示用户文件。

<?php

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Contracts\Support\Renderable
     */
    public function index()
    {
        $files = Storage::files('files/' . auth()->user()->id);

        return view('home', compact('files'));
    }

home.blade.php

<ul class="list-group">
    @forelse ($files as $file)
        <li class="list-group-item">
            <a href="{{ route('downloadFile', basename($file)) }}" rel="external nofollow" >
                {{ basename($file) }}
            </a>
        </li>
    @empty
        <li class="list-group-item">You have no files</li>
    @endforelse
</ul>

就是这样! 我们现在在使用静态加密! 我们创建了供用户上传文件的表单,对这些文件进行加密,并且仅在上传文件的用户要求时才对其解密。

当然,在生产中,需要采取更多的安全措施,而 FileVault 扩展包旨在这方面为您提供帮助。

如,您可能希望将用户上传的大文件存储在 Amazon S3 中,该扩展包支持文件加密 / 流解密。

您可能还想为每个用户或每个文件使用不同的加密密钥,这对于 FileVault 扩展包也是可能的。

以上就是浅谈Laravel中如何对大文件进行加密的详细内容,更多关于Laravel中如何对大文件进行加密的资料请关注我们其它相关文章!

时间: 2021-05-28

laravel使用组件实现微信网页授权登入

laravel框架中的实现简单实现微信网页授权登入 首先引入基于laravel的easywechat的组件,laravel版本5.8 $ cd laravel $ composer require "overtrue/laravel-wechat:~5.0" 参考组件地址:https://github.com/overtrue/laravel-wechat 然后呢因为下载过程会比较缓慢所以可以先根据官方提供的方式配置一下该组件的中间件 根据官方提供的测试代码在routes/web.ph

laravel 5.3中自定义加密服务的方案详解

前言 本文介绍的是laravel 5.3中自定义加密服务的方案,利用laravel的服务容器,实现自定义加密服务注册(示例是支持长字符串的RSA加密),下面来看看详细的介绍: 创建加密解密服务类 文件地址 /app/Service/Common/CryptService.php 代码如下 下面这个是个人写的支持长字符串的RSA加密类作为示例,自定义加密的话只需更改这个文件的代码就好,其它操作只是为了实现依赖注入. <?php namespace App\Service\Common; class

Laravel 数据库加密及数据库表前缀配置方法

报错问题:DecryptException in Encrypter.php line 148: The MAC is invalid. 如何运行 php artisan key:generate 这个命令 需要安装Composer D: 回到D盘 ,cd 到laravel根目录 然后运行 php artisan key:generate:前提是你项目根目录下有个.env文件,如果没有,敲命令 "echo 内容 >.env",生成一个.env 文件(不带引号哦),然后把根路径下的

Laravel中的where高级使用方法实例讲解

有时候项目中需要进行多个字段搜索就可以用到此方法 在Laravel中的可以同时使用多个where,所以我们可以每个字段分配一个where() 然后在每个where()中去闭包判断 $username = '';// 收货人姓名 $hospital_id = ''; // 医院id # 判断是否有姓名搜索 if (!empty($request->username)) { $username = $request->username; } # 判断是否有医院搜索 if (!empty($requ

Laravel 重写日志,让日志更优雅

更改目的: 重写了日志格式 加入trace,一次请求的唯一标识 加入error级别信息推送,事例中使用企业微信群助手 让我们可以更及时.更优雅.更方便追踪日志信息 有助于初学者了解Laravel框架 1.将文件 AppTool.php.Logger.php.LogServiceProvider.php复制到 app/Providers文件夹下,将文件BaseCommand.php复制到App\Console下 2 .在config/app.php→providers中加入 'providers'

Laravel统一封装接口返回状态实例讲解

前后端分离,接口返回封装方便你我他(方便前后端合作开发) 在Laravel中可以在公共继承的Controller.php写方法进行调用返回 app/Http/Controllers/Controller.php 成功返回 /** * $msg 返回提示消息 * $data 返回数据 */ public function success($msg,$data = []) { return response()->json([ 'status' => true, 'code' => 200,

Laravel的加密解密与哈希实例讲解

一.加密解密 当你的应用程序中需要用到加密和解密的地方时可以使用Laravel自带的加密解密工具. Laravel 的加密机制使用的是 OpenSSL 所提供的 AES-256 和 AES-128 加密.强烈建议你使用 Laravel 内建的加密工具,而不是用其它的加密算法.所有 Laravel 加密之后的结果都会使用消息认证码 (MAC) 签名,使其底层值不能在加密后再次修改. 相应的配置文件 config/app.php 首先生成 APP_KEY php artisan key:genera

Java-web中利用RSA进行加密解密操作的方法示例

前言 最近在看,网络安全方面的问题,我们可以使用RSA进行非对称加密防止,获取用户信息.首先我们看下java下操作RSA进行加密解密算法,代码如下: package com.jb.test; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmExcepti

Java实现的DES加密解密工具类实例

本文实例讲述了Java实现的DES加密解密工具类.分享给大家供大家参考,具体如下: 一个工具类,很常用,不做深入研究了,那来可直接用 DesUtil.java package lsy; import java.security.Key; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; imp

JS使用插件cryptojs进行加密解密数据实例

本文实例讲述了JS使用插件cryptojs进行加密解密数据.分享给大家供大家参考,具体如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Testing websoc

基于php实现的php代码加密解密类完整实例

本文实例讲述了基于php实现的php代码加密解密类.分享给大家供大家参考,具体如下: php 代码加密类,大家可以根据自己的需求进行修改,原类如下,该实例在ubuntu下测试没有问题. <?php class Encryption{ private $c='';//存储密文 private $s='',$q1,$q2,$q3,$q4,$q5,$q6;//存储生成的加密后的文件内容 //如果不设置一个值,isset会表示不存在: private $file='';//读取文件的路径 private

php结合md5的加密解密算法实例

本文实例讲述了php结合md5的加密解密算法.分享给大家供大家参考,具体如下: <?php /* * Created on 2016-9-30 * */ function encrypt($data, $key) { $key = md5($key); $x = 0; $len = strlen($data); $l = strlen($key); for ($i = 0; $i < $len; $i++) { if ($x == $l) { $x = 0; } $char .= $key{$

PHP实现的DES加密解密封装类完整实例

本文实例讲述了PHP实现的DES加密解密封装类.分享给大家供大家参考,具体如下: <?php /** * PHP版DES加解密类 * 可与java的DES(DESede/CBC/PKCS5Padding)加密方式兼容 * */ class CryptDes { var $key; var $iv; function CryptDes($key, $iv){ $this->key = $key; $this->iv = $iv; } function encrypt($input){ $s

C#实现的AES加密解密完整实例

本文实例讲述了C#实现的AES加密解密.分享给大家供大家参考,具体如下: /****************************************************************** * 创建人:HTL * 说明:C# AES加密解密 *******************************************************************/ using System; using System.Security.Cryptography;

PHP实现的简单AES加密解密算法实例

本文实例讲述了PHP简单AES加密解密算法.分享给大家供大家参考,具体如下: /* * 实现AES加密 * $str : 要加密的字符串 * $keys : 加密密钥 * $iv : 加密向量 * $cipher_alg : 加密方式 */ function ecryptdString($str,$keys="6461772803150152",$iv="8105547186756005",$cipher_alg=MCRYPT_RIJNDAEL_128){ $enc

Java探索之Thread+IO文件的加密解密代码实例

这篇文章向大家分享了几段代码,主要是关于Thread+IO文件的加密解密,下面看看具体代码: 加密启动线程 package com.hz.subsection; import java.io.File; public class enCodeFileThread extends Thread { public Files files; public File file; public File dst; public enCodeFileThread(String name,Files file

php中base64_decode与base64_encode加密解密函数实例

本文实例讲述了php中base64_decode与base64_encode加密解密函数.分享给大家供大家参考.具体分析如下: 这两个函数在php中是用得对php代码进行加密与解密码的base64_encode是加密,而base64_decode是解密了,下面我们看两个简单实例. base64_encode语法:string base64_decode(string data); 复制代码 代码如下: $str='d3d3LmpiNTEubmV0IOiEmuacrOS5i+Wutg==';