我想在添加/编辑某些表单域时对其进行加密,并在通过cake查找它们时对其进行解密。这是v2.7.2中对我有用的代码:
core.php
Configure::write('Security.key','secretkey');
app / model / patient.php。
public $encryptedFields = array('patient_surname', 'patient_first_name');
public function beforeSave($options = array()) {
foreach($this->encryptedFields as $fieldName){
if(!empty($this->data[$this->alias][$fieldName])){
$this->data[$this->alias][$fieldName] = Security::encrypt(
$this->data[$this->alias][$fieldName],
Configure::read('Security.key')
);
}
}
return true;
}
public function afterFind($results, $primary = false) {
foreach ($results as $key => $val) {
foreach($this->encryptedFields as $fieldName) {
if (@is_array($results[$key][$this->alias])) {
$results[$key][$this->alias][$fieldName] = Security::decrypt(
$results[$key][$this->alias][$fieldName],
Configure::read('Security.key')
);
}
}
}
return $results;
}
据我了解,我必须用模型的生成实体替换$ this-> data [],并用虚拟字段替换afterFind方法,但是我不能将它们全部放在一起。
有多种方法可以解决此问题(请注意,以下代码是未经测试的示例代码!在使用任何此类代码之前,您应该首先了解新的基础知识)。
一种是自定义数据库类型,它将在将值绑定到数据库语句时进行加密,并在获取结果时进行解密。那是我希望的选择。
这是一个简单的示例,假设db列可以容纳二进制数据。
src /数据库/类型/CryptedType.php
这应该是自言自语的,转换为数据库时进行加密,转换为PHP时进行解密。
<?php
namespace App\Database\Type;
use Cake\Database\Driver;
use Cake\Database\Type;
use Cake\Utility\Security;
class CryptedType extends Type
{
public function toDatabase($value, Driver $driver)
{
return Security::encrypt($value, Security::salt());
}
public function toPHP($value, Driver $driver)
{
if ($value === null) {
return null;
}
return Security::decrypt($value, Security::salt());
}
}
src / config / bootstrap.php
注册自定义类型。
use Cake\Database\Type;
Type::map('crypted', 'App\Database\Type\CryptedType');
src / Model / Table / PatientsTable.php
最后,将可加密的列映射到注册的类型,就是这样,从现在开始,所有内容都会自动处理。
// ...
use Cake\Database\Schema\Table as Schema;
class PatientsTable extends Table
{
// ...
protected function _initializeSchema(Schema $table)
{
$table->columnType('patient_surname', 'crypted');
$table->columnType('patient_first_name', 'crypted');
return $table;
}
// ...
}
参见 **[食谱
数据库访问和ORM>数据库基础>添加自定义类型](http://book.cakephp.org/3.0/en/orm/database-
basics.html#adding-custom-types)**
较不干燥且紧密的耦合方法(基本上是2.x代码的一部分)将使用beforeSave
回调/事件和结果格式化程序。结果格式化程序可以例如附加在beforeFind
事件/回调中。
在beforeSave
刚刚设置/获取值/从通过实体实例,你可以利用Entity::has()
,Entity::get()
并且Entity::set()
,甚至使用数组访问,因为实体实施ArrayAccess
。
结果格式化程序基本上是一个after find挂钩,您可以使用它轻松地遍历结果并进行修改。
这是一个基本示例,不需要进一步解释:
// ...
use Cake\Event\Event;
use Cake\ORM\Query;
class PatientsTable extends Table
{
// ...
public $encryptedFields = [
'patient_surname',
'patient_first_name'
];
public function beforeSave(Event $event, Entity $entity, \ArrayObject $options)
{
foreach($this->encryptedFields as $fieldName) {
if($entity->has($fieldName)) {
$entity->set(
$fieldName,
Security::encrypt($entity->get($fieldName), Security::salt())
);
}
}
return true;
}
public function beforeFind(Event $event, Query $query, \ArrayObject $options, boolean $primary)
{
$query->formatResults(
function ($results) {
/* @var $results \Cake\Datasource\ResultSetInterface|\Cake\Collection\CollectionInterface */
return $results->map(function ($row) {
/* @var $row array|\Cake\DataSource\EntityInterface */
foreach($this->encryptedFields as $fieldName) {
if(isset($row[$fieldName])) {
$row[$fieldName] = Security::decrypt($row[$fieldName], Security::salt());
}
}
return $row;
});
}
);
}
// ...
}
要对此进行一点解耦,您还可以将其移为一个行为,以便您可以轻松地在多个模型之间共享它。
现在数据被加密保存在数据库中...问题是我们仍然需要能够在MySQL上使用aes_decrypt来解密信息,而它返回null。 在CakePHP 3上,config/app.php: 然后使用: 我的MYSQL表: 注意:地址和注释只是为了测试。 然后,在CakePHP上,我创建了一个自定义数据库类型: 最后,将加密列映射到注册类型,就这样,从现在开始,所有的事情都将自动处理。
我目前正在尝试解析我通过Chrome中的Postman插件发送的。然而,我得到的输出如下: 当我尝试调试时,会得到这个输出。当我尝试时,我得到一个空数组,所以我假设数据的格式不正确(只是一个字符串)。在我写我自己的算法之前,我想确定我没有用这个算法重新发明轮子。我做错什么了?或者,如果没有,是否存在一些CakePHP3函数来处理这个问题? 更新 我发现了代码中的错误,路由过程似乎以某种方式将pos
问题内容: 我正在尝试使用Java Cryto在Java中进行简单的AES加密,然后可以使用OpenSSL在ObjectiveC中对其进行解密。 因为我没有在ObjectiveC方面进行操作,所以我想使用openSSL命令行确保它可以正常工作,但是我总是会收到“错误的魔术数字” 这是我的Java代码 现在可以按预期运行,文件“ test-encrypted.txt”确实已加密,并且“ test-d
我想在Java文件中存储一个加密的密码。我看到了一个使用javax.crypto的解决方案,但问题是密钥是动态生成的,并且是随机的。 有没有办法告诉javax.crypto方法: 这是否可以替换为基于某个私钥生成一次的我自己的密钥? 有谁能给我指出一些如何做到这一点的资源吗?
因此,这种特殊的异常非常常见,但我的问题与通常被问到的略有不同。 我有一个AES解密和加密函数,定义如下: 现在,如果我像这样执行单个解密: 字节数组输出很好。而如果我执行双重加密/解密: 我得到了著名的<code>javax.crypto。BadPaddingException:给定的最终块未正确填充异常。请注意,和只是整数(假设它们都是0)。目前,IVBytes只是一个大小为16的空字节数组,