Php 解密Laravel加密值
我有一个Laravel应用程序,它使用默认的Laravel可加密特性进行加密和解密 现在我需要将数据库迁移到另一个数据库 我已经创建了一个SQL脚本来处理数据迁移,但是在迁移过程中,我需要对一些字段进行一些检查。例如:Php 解密Laravel加密值,php,mysql,laravel,encryption,Php,Mysql,Laravel,Encryption,我有一个Laravel应用程序,它使用默认的Laravel可加密特性进行加密和解密 现在我需要将数据库迁移到另一个数据库 我已经创建了一个SQL脚本来处理数据迁移,但是在迁移过程中,我需要对一些字段进行一些检查。例如: insert into test.table (valueA, valueB, valueC) SELECT tb.a, tb.b, tc.c from db2.tableB tb join test.tableC
insert into test.table
(valueA, valueB, valueC)
SELECT tb.a, tb.b, tc.c
from db2.tableB tb
join test.tableC tc on tb.id = tc.tb_id;
UPDATE test.table
SET valueD = CASE
WHEN valueA = 'example' THEN 1
ELSE 0
END;
SELECT AES_DECRYPT(from_base64(valueA),'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') from
test.table;
问题是其中一些字段是加密的。
例如,valueA将类似于:
EYJPDII6IMTTTUTHN0DFT2N3QKT6REDAAMIYWG9PSISINZHBHVLIKOIAKFIA0RFTVDCSU1HWY3N0VUT09IIWIBWFJIJOIOGI1ZJY5ODVKYZMZMZYNZMZMZYNZMZMZYMWWNM2RZDZDZDYLZVLOCJ9
我尝试使用Laravel中的APP_密钥使用AES_DECRYPT(),但脚本总是返回null。例如:
insert into test.table
(valueA, valueB, valueC)
SELECT tb.a, tb.b, tc.c
from db2.tableB tb
join test.tableC tc on tb.id = tc.tb_id;
UPDATE test.table
SET valueD = CASE
WHEN valueA = 'example' THEN 1
ELSE 0
END;
SELECT AES_DECRYPT(from_base64(valueA),'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') from
test.table;
始终返回NULL
显然,这把钥匙是为了这篇文章而隐藏的
我认为这是因为Laravel在加密时使用open_ssl,而AES_DECRYPT不使用。我说得对吗
有没有办法在运行迁移脚本之前解密数据库,或者在更新期间解密SELECT语句中的值
更新: 为了使用“AES-256-CBC”,我设置了MySql。 请记住,在Laravel中,应用程序密钥类似于:“base64:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx” 这就是我现在要做的:
SET block_encryption_mode = 'aes-256-cbc';
SET @key_str = to_base64('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
SET @init_vector = (SELECT LEFT(CONVERT(encryptedVal USING binary), 16) from tableA where id =1);
SELECT encryptedVal, AES_DECRYPT(encryptedVal,@key_str,@init_vector) from tableA where id = 1;
顺便说一句,我仍然有空值。
如果有人需要任何帮助,我们将不胜感激。我最终创建了一个从Laravel调用的脚本,用于解密我需要的表和字段:
class DecryptDatabase extends Command
{
protected $tables = (array(
"tableA" => array(
"pk" => 'id',
"encrypted" => array('valueA', 'valueB', 'valueC'),
"name" => "tableA"
),
"users" => array(
"pk" => 'id',
"encrypted" => array('name', 'surname', 'profession'),
"name" => "users"
),
));
public function handle()
{
foreach($this->tables as $t) {
$columns = implode(',', $t['encrypted']);
$q = DB::connection('mysql2')->select('select ' . $t['pk']. ','. $columns . ' from '. $t['name']);
foreach($q as $result)
{
$pk = $t['pk'];
try {
foreach($t['encrypted'] as $enc) {
if($result->$enc != null){
$decrypted = Crypt::decrypt($result->$enc);
$query = DB::connection('mysql3')
->table($t['name'])
->where($t['pk'], $result->$pk)
->update([$enc => $decrypted]);
}
}
} catch (DecryptException $e) {
echo ("Error in decryption: ". $e);
}
}
}
echo "Decryption terminated";
return 0;
}
}
此脚本解密$tables变量中定义的所有字段。
它使用“mysql2”连接中定义的数据库作为加密值的源,然后将解密值存储在“mysql3”连接中定义的数据库中
第一个数据库是原始数据库,而第二个数据库是第一个数据库的精确副本。我这样做是为了在解密时保持原始数据库不变,以防止在解密过程中出现错误时数据损坏
解密数据库后,我可以正确运行迁移脚本,然后按照解密函数的相反方向再次加密数据库。如果有人需要,我最终创建了一个名为from Laravel的脚本,对我需要的表和字段进行解密:
class DecryptDatabase extends Command
{
protected $tables = (array(
"tableA" => array(
"pk" => 'id',
"encrypted" => array('valueA', 'valueB', 'valueC'),
"name" => "tableA"
),
"users" => array(
"pk" => 'id',
"encrypted" => array('name', 'surname', 'profession'),
"name" => "users"
),
));
public function handle()
{
foreach($this->tables as $t) {
$columns = implode(',', $t['encrypted']);
$q = DB::connection('mysql2')->select('select ' . $t['pk']. ','. $columns . ' from '. $t['name']);
foreach($q as $result)
{
$pk = $t['pk'];
try {
foreach($t['encrypted'] as $enc) {
if($result->$enc != null){
$decrypted = Crypt::decrypt($result->$enc);
$query = DB::connection('mysql3')
->table($t['name'])
->where($t['pk'], $result->$pk)
->update([$enc => $decrypted]);
}
}
} catch (DecryptException $e) {
echo ("Error in decryption: ". $e);
}
}
}
echo "Decryption terminated";
return 0;
}
}
此脚本解密$tables变量中定义的所有字段。
它使用“mysql2”连接中定义的数据库作为加密值的源,然后将解密值存储在“mysql3”连接中定义的数据库中
第一个数据库是原始数据库,而第二个数据库是第一个数据库的精确副本。我这样做是为了在解密时保持原始数据库不变,以防止在解密过程中出现错误时数据损坏
解密数据库后,我可以正确运行迁移脚本,然后按照解密函数的相反方向再次加密数据库。我发现有迹象表明,Laravel使用AES+HMAC进行完整性/身份验证,但还没有规范,好像他们不希望您故意找到它似的。可能它使用了。嗨@MaartenBodewes。是的,它使用了你链接的特征。根据您在那里读到的内容,您知道(如果)我如何在MySql Workbench中直接解密吗?我有点困惑,要么是
IV+CBC(纯文本)
,要么是IV+CBC(纯文本)+MAC
。查看AES\u DECRYPT
,它默认为使用系统变量的ECB模式,并且在参数中包含IV,而不是在密文中。与大多数DB加密功能一样,它有点难以置信的愚蠢;相对较少的数据库加密似乎是由专家设计的。但是,是的,将模式更改为CBC,从密文中提取IV(前16个字节),然后解密。如果它不起作用,可能是因为MAC仍然存在。再次感谢您的回答@MaartenBodewes。我试图在MySql中使用SET block\u encryption\u mode='aes-256-CBC
将模式更改为CBC。顺便说一句,我得到了以下错误:错误代码:1193。未知系统变量“块加密模式”
。这听起来真的很奇怪,因为如果我运行SHOW变量,比如“%version%”代码>我得到'version',10.4.11-MariaDB'
,因此块加密模式应该出现在我的版本中。知道为什么会这样吗?不,也许在搜索后再问一个问题<代码>设置块加密模式='aes-256-cbc'代码>从字面上看似乎出现在文档中。我试着远离DB编程,我更像是一个安全专家。我发现有迹象表明Laravel使用AES+HMAC进行完整性/身份验证,但还没有规范,好像他们不想让你故意找到它。可能它使用了。嗨@MaartenBodewes。是的,它使用了你链接的特征。根据您在那里读到的内容,您知道(如果)我如何在MySql Workbench中直接解密吗?我有点困惑,要么是IV+CBC(纯文本)
,要么是IV+CBC(纯文本)+MAC
。查看AES\u DECRYPT
,它默认为使用系统变量的ECB模式,并且在参数中包含IV,而不是在密文中。与大多数DB加密功能一样,它有点难以置信的愚蠢;相对较少的数据库加密似乎是由专家设计的。但是,是的,将模式更改为CBC,从密文中提取IV(前16个字节),然后解密。如果它不起作用,可能是因为MAC仍然存在。再次感谢您的回答@MaartenBodewes。我试图在MySql中使用SET block\u encryption\u mode='aes-256-CBC
将模式更改为CBC。顺便说一句,我得到了以下错误:错误代码:1193。未知系统变量“块加密模式”
。这听起来真的很奇怪,因为如果我运行SHOW变量,比如“%version%”代码>我得到'version',10.4.11-MariaDB'
,因此块加密模式应该出现在我的版本中。知道为什么吗