jdforsythe/elocryptlumen

轻松实现Eloquent属性自动加密和解密。

1.0.2 2016-04-30 02:12 UTC

This package is not auto-updated.

Last update: 2024-09-14 17:53:42 UTC


README

Build Status

自动加密和解密Lumen 5 Eloquent值。

请先阅读

加密值通常比纯文本值长。有时长得多。您可能需要扩展数据库表中的列宽度以存储加密值。

如果您正在加密长字符串,例如JSON blob,则加密值可能比VARCHAR字段支持的还要长,您可能需要将列类型扩展到TEXT或LONGTEXT。

这是做什么的?

通过在模型属性中加密数据并从模型属性中解密数据,它在Lumen应用程序中透明地加密和解密数据库表中的列。

所有加密的数据都带有标记(目前为__ELOCRYPT__;),以便可以轻松识别加密数据。

这支持存储加密或非加密数据的列,以便更容易迁移。无论数据是否加密,都可以正确地从列中读取,但将其保存回列时将自动加密。

贡献者

这是Del的Laravel 5 Elocrypt包移植版,以便在没有启用外观的情况下在Lumen中使用。我已做出以下更改

  • 直接加载'encrypter'而不是通过Crypt外观,以便在Lumen中使用而无需启用外观

  • 允许在.env文件中设置elocrypt前缀(ELOCRYPT_PREFIX=

原始Laravel 5包在这里:https://github.com/delatbabel/elocrypt

原始Laravel 4包在这里:https://github.com/dtisgodsson/elocrypt

安装

您可以通过将以下内容添加到您的composer.json文件来通过Composer安装此包

    "require": {
        "jdforsythe/elocryptlumen": "~1.0"
    }

然后,您必须运行以下命令

    composer update

用法

只需在您希望应用加密的任何Eloquent模型中引用Elocrypt特质,并定义一个包含要加密的属性列表的$encrypts数组。

例如

    use Jdforsythe\ElocryptLumen\Elocrypt;

    class User extends Eloquent {

        use Elocrypt;

        /**
         * The attributes that should be encrypted on save.
         *
         * @var array
         */
        protected $encrypts = [
            'address_line_1', 'first_name', 'last_name', 'postcode'
        ];
    }

您可以将$casts$encrypts结合使用来存储加密数组。数组将首先转换为JSON然后加密。

例如

    use Jdforsythe\ElocryptLumen\Elocrypt;

    class User extends Eloquent {

        use Elocrypt;

        protected $casts = ['extended_data' => 'array'];

        protected $encrypts = ['extended_data'];
    }

它是如何工作的?

通过包含Elocrypt特质,Eloquent提供的setAttribute()和getAttributeFromArray()方法被覆盖,增加了一步。这个附加步骤只是检查要设置或获取的属性是否包含在模型上的$encrypts数组中,并根据需要进行加密/解密。

Illuminate\Database\Eloquent\Model中方法总结

这是调查了Laravel v 5.1.12的Eloquent模型类中的主要方法,并检查了这些模型如何设置属性以及它们如何受此特质的影响。

  • 构造函数 -- 调用fill()
  • fill() -- 调用setAttribute(),该方法已扩展以加密数据。
  • hydrate() -- 待定
  • create() -- 调用构造函数,因此fill()
  • firstOrCreate -- 调用构造函数
  • firstOrNew -- 调用构造函数
  • updateOrCreate -- 调用fill()
  • update() -- 调用fill()
  • toArray() -- 调用attributesToArray()
  • jsonSerialize() -- 调用toArray()
  • toJson() -- 调用toArray()
  • attributesToArray() -- 调用 getArrayableAttributes().
  • getAttribute -- 调用 getAttributeValue()
  • getAttributeValue -- 调用 getAttributeFromArray()
  • getAttributeFromArray -- 调用 getArrayableAttributes()
  • getArrayableAttributes -- 在此处已扩展以解密数据。
  • setAttribute -- 在此处已扩展以加密数据。
  • getAttributes -- 在此处已扩展以解密数据。

密钥和IV

Lumen Encrypter 服务的密钥设置在 .env 文件中的 APP_KEY。Lumen 默认使用 AES-256-CBC 加密算法。

加密的IV是随机生成的。

常见问题解答

手动加密数据

您可以使用 encryptedAttribute()decryptedAttribute() 函数手动加密或解密数据。以下是一个示例:

    $user = new User();
    $encryptedEmail = $user->encryptedAttribute(Input::get("email"));

加密与搜索

由于数据已被加密,因此您无法在加密数据上进行搜索。比较加密值需要固定的IV,这会引入安全风险。

如果您需要对数据进行搜索,则可以选择以下做法:

  • 不加密,或
  • 对数据进行哈希处理,并使用哈希值而不是加密值进行搜索。使用SHA256等众所周知的哈希算法。

您可以将哈希值和加密值都存储起来,使用哈希值进行搜索,并在其他用途中检索加密值。

加密与认证

对于认证而言,由于认证需要用户搜索,因此与搜索相同的问题也会出现。

如果您有一个包含加密用户数据(包括登录数据,例如电子邮件)的认证表,这将阻止Auth::attempt函数正常工作。例如,以下代码将无法正常工作:

    $auth = Auth::attempt(array(
                "email"     =>  Input::get("email"),
                "password"  =>  Input::get("password"),
    ), $remember);

对于搜索,比较加密的电子邮件地址将不会工作,因为这需要固定的IV,这会引入安全风险。

您需要做的是使用SHA256或RIPE-MD160等众所周知的哈希函数对电子邮件地址进行哈希处理,而不是加密,然后在Auth::attempt函数中比较哈希值。

如果您需要访问电子邮件地址,则可以将哈希值和加密值都存储起来,使用哈希值进行认证,并在其他用途(例如发送电子邮件)中检索加密值。