我使用Symfony 2與Doctrine 2.在哪裏加密/解密我的數據?
我需要使用加密服務加密我的實體中的字段,我想知道我應該在哪裏放置這個邏輯。
我正在使用控制器>服務>存儲庫架構。
我想知道如果一個聽衆是一個好主意,我的主要擔心是,如果我的實體存儲加密,如果我在飛行中解密它的狀態它將會改變,我不知道這是一個好理念。
你將如何實現這一點?
我使用Symfony 2與Doctrine 2.在哪裏加密/解密我的數據?
我需要使用加密服務加密我的實體中的字段,我想知道我應該在哪裏放置這個邏輯。
我正在使用控制器>服務>存儲庫架構。
我想知道如果一個聽衆是一個好主意,我的主要擔心是,如果我的實體存儲加密,如果我在飛行中解密它的狀態它將會改變,我不知道這是一個好理念。
你將如何實現這一點?
我不知道它是否是正確的方法,但我最近通過創建custom mapping type來實現這一點,按照Doctrine文檔。像下面這樣:
class EncryptedStringType extends TextType
{
const MYTYPE = 'encryptedstring'; // modify to match your type name
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return base64_decode($value);
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return base64_encode($value);
}
public function getName()
{
return self::MYTYPE;
}
}
我註冊這個類型在我的包類:
class MyOwnBundle extends Bundle
{
public function boot()
{
$em = $this->container->get("doctrine.orm.entity_manager");
try
{
Type::addType("encryptedstring", "My\OwnBundle\Type\EncryptedStringType");
$em->
getConnection()->
getDatabasePlatform()->
registerDoctrineTypeMapping("encryptedstring", "encryptedstring");
} catch (\Doctrine\DBAL\DBALException $e)
{
// For some reason this exception gets thrown during
// the clearing of the cache. I didn't have time to
// find out why :-)
}
}
}
,然後我就能夠創建我的實體,例如當參考吧:
/**
* @ORM\Column(type="encryptedstring")
* @Assert\NotBlank()
*/
protected $name;
這是一個快速實施,所以我很想知道正確的做法。我還假定你的加密服務是容器中可用的東西;我不知道這將是多麼可行/可服務傳遞到這樣無論是自定義類型... :-)
richsage的答案是相當不錯的,但我不會在註冊自定義類型捆綁類文件。我們建議您使用config.yml像這樣:
# ./app/config/confi
doctrine:
dbal:
driver: "%database_driver%"
{{ etc, etc }}
types:
encrypted_string: MyCompany\MyBundle\Type\EncryptedStringType
然後只需確保在你的EncryptedStringType類,你指定的getName函數返回encrypted_string。
現在在您的模型定義(或註釋)中,您可以使用encrypted_string類型。
不錯,這是更清潔:-) – richsage
要擴大richsage和targnation的偉大的答案,注入的依賴的一種方式(例如,cypto服務)到自定義學說映射類型,可以使用一個靜態屬性和setter:
// MyBundle/Util/Crypto/Types/EncryptedString.php
class EncryptedString extends StringType
{
/** @var \MyBundle\Util\Crypto */
protected static $crypto;
public static function setCrypto(Crypto $crypto)
{
static::$crypto = $crypto;
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
$value = parent::convertToDatabaseValue($value, $platform);
return static::$crypto->encrypt($value);
}
public function convertToPHPValue($value, AbstractPlatform $platform)
{
$value = parent::convertToPHPValue($value, $platform);
return static::$crypto->decrypt($value);
}
public function getName()
{
return 'encrypted_string';
}
}
配置是這樣的:
// MyBundle/MyBundle.php
class MyBundle extends Bundle
{
public function boot()
{
/** @var \MyBundle\Util\Crypto $crypto */
$crypto = $this->container->get('mybundle.util.crypto');
EncryptedString::setCrypto($crypto);
}
}
# app/Resources/config.yml
doctrine:
dbal:
types:
encrypted_string: MyBundle\Util\Crypto\Types\EncryptedString
# MyBundle/Resources/config/services.yml
services:
mybundle.util.crypto:
class: MyBundle\Util\Crypto
arguments: [ %key% ]
您好,感謝您的回答,這絕對是一個好主意,但是我不知道我怎麼會通過我的私鑰? 假設我使用構造函數將EncryptionService傳遞給了我的Custom類型,但我仍然需要將它傳遞給一個用於加密的密鑰,但是,因爲在持久化和保溼實體時使用了類型,所以我不知道如何才能這樣做 – Trent
是的,在我們的例子中,我們使用了'mcrypt_ *'函數,並且由於時間限制而對iv和passphrase等進行了硬編碼,但是我不知道您是否可以將類型創建爲服務並以這種方式傳遞參數。似乎缺乏有關如何有效地做到這一點的信息! – richsage
是的,我實際上使用mcrypt_ *函數,但加密數據的密鑰是動態生成的,因此我無法對其進行硬編碼。 – Trent