首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >LIBSODIUM像AES_DECRYPT一样解密mysql查询中数据

LIBSODIUM像AES_DECRYPT一样解密mysql查询中数据
EN

Stack Overflow用户
提问于 2018-08-24 16:51:15
回答 1查看 547关注 0票数 1

我有一些sql查询,其中im选择靠近用户位置的行。使用AES_DECRYPT,我可以在查询中执行以下操作:

代码语言:javascript
复制
AES_DECRYPT(lat, :key)

我需要查询中的解密后的值:

对它们进行排序在给定区域中定界条目,并对其他查询进行类似的操作

一个查询的简短示例:

代码语言:javascript
复制
SELECT something,
(
    6371 * acos( cos( radians(".$userdatafromdbfetchedbefore['lat'].") ) * cos( radians( AES_DECRYPT(lat, :key) ) ) * cos( radians( AES_DECRYPT(lng, :key) ) - radians(".$userdatafromdbfetchedbefore['lng'].") ) + sin( radians(".$userdatafromdbfetchedbefore['lat'].") ) * sin(radians( AES_DECRYPT(lat, :key))) )
) AS distance
FROM 
    table
HAVING 
    distance <= ".$userdatafromdbfetchedbefore['maxrange']."
ORDER BY 
    e.orderdate 
DESC,
    distance  
ASC
LIMIT
    ".$start.", ".$offset."

我不能在不同的查询中选择所有行并用php操作结果,这对于100k以上的行来说是非常无效的,而用户附近的行可能只有~100行。

对我来说保持位置数据加密是非常重要的,直到现在我才开始我的项目,因为不安全的加密。

现在我的问题是,我怎样才能用php新实现的thing来做同样的事情?

我找不到一个可行的例子。我刚刚发现了一个使用盲索引的例子,如果你像存储的一样加密搜索词,你可以找到一个值,但在我的例子中没有帮助,因为我需要获得值来在同一个查询中运行距离公式。

EN

回答 1

Stack Overflow用户

发布于 2018-10-13 15:35:59

MySQL中没有内置AES_ENCRYPT(),因此您不能仅从MySQL查询中调用与within等效的东西来获得您期望的结果。

但是,另一种方法是使用像CipherSweet这样的库,它提供了可搜索的身份验证加密。在决定使用它之前,请确保您了解its featureslimitations

代码语言:javascript
复制
<?php
use ParagonIE\CipherSweet\CipherSweet;
use ParagonIE\CipherSweet\EncryptedRow;
use ParagonIE\CipherSweet\Transformation\AlphaCharactersOnly;
use ParagonIE\CipherSweet\Transformation\FirstCharacter;
use ParagonIE\CipherSweet\Transformation\Lowercase;
use ParagonIE\CipherSweet\Backend\FIPSCrypto;
use ParagonIE\CipherSweet\KeyProvider\StringProvider;

$provider = new StringProvider(
    // Example key, chosen randomly, hex-encoded:
    'a981d3894b5884f6965baea64a09bb5b4b59c10e857008fc814923cf2f2de558'
);
$engine = new CipherSweet($provider, new FIPSCrypto());

/** @var CipherSweet $engine */
$row = (new EncryptedRow($engine, 'contacts'))
    ->addTextField('first_name')
    ->addTextField('last_name')
    ->addFloatField('latitude')
    ->addFloatField('longitude');

// Notice the ->addRowTransform() method:
$row->addCompoundIndex(
    $row->createCompoundIndex(
        'contact_first_init_last_name',
        ['first_name', 'last_name'],
        64, // 64 bits = 8 bytes
        true
    )
        ->addTransform('first_name', new AlphaCharactersOnly())
        ->addTransform('first_name', new Lowercase())
        ->addTransform('first_name', new FirstCharacter())
        ->addTransform('last_name', new AlphaCharactersOnly())
        ->addTransform('last_name', new Lowercase())
);

$prepared = $row->prepareRowForStorage([
    'first_name' => 'Jane',
    'last_name' => 'Doe',
    'latitude' => 52.52,
    'longitude' => -33.106,
    'extraneous' => true
]);

var_dump($prepared);

您应该会看到与此类似的内容。[0]中的值将更改,但[1]中的值不会更改。这是因为[0]包含带有(某些字段已加密)的行数据。[1]只包含盲索引(稍后在SELECT查询中可用)。

代码语言:javascript
复制
array(2) {
  [0]=>
  array(5) {
    ["first_name"]=>
    string(141) "fips:nrtzoaxvPIOA7jPskWVwJmC0q8WJqrsnqjPh3ifNPsRd2TAx6OwTDfSiMVCXSsSRNQb_nxJlW7TbAtf5UvQRWWKTGhk_kXxpZKdnTrpjbmxi0IgstSrZ126Qz6E0_lvjew0Ygw=="
    ["last_name"]=>
    string(137) "fips:98f5CLB24w0zSqCGPR0D2oq9wQvUwzxo_byAp6mKgMgoJkUHZX1oTtk4Cm8FXI7fsUI8HOG5sKQFGRn6cXMw1EOMGgpXZqiXEDb3jxEbg9s95d4g2NeVd4xs2tmX0xlZ0nSM"
    ["latitude"]=>
    string(145) "fips:d3TVGfnRFlvWxbfihgHqjpXlXU3HtkCAHzM0-4f1l5dAeQf2Vk5RDDVOGMQNM09r0O4UOAub6QTyHGezQ0bWKQ5omqoYCTBJE0Uf_2DSPfO7U4dG74phaP04iFgqpJ8G41q54Kv5t54="
    ["longitude"]=>
    string(145) "fips:IcnUnBZZOxJPYXk-F3v12O_krNb9JsexljiV4gJzgctTpxLFm7ql0tJRF7xP3wLrUtd1VyfYBf75ot7iOSIIIFqsuyKZQdI9UyKbqd87RTMsHbHgPouxgZBg1urlqpuWqbOYEFGiti4="
    ["extraneous"]=>
    bool(true)
  }
  [1]=>
  array(1) {
    ["contact_first_init_last_name"]=>
    array(2) {
      ["type"]=>
      string(13) "w6dsrxbathjze"
      ["value"]=>
      string(16) "546b1ffd1f83c37a"
    }
  }
}

请注意,即使输入的精度级别不同,浮点域也将始终生成固定长度的输出。这是故意的,以防止攻击者从密文长度中获取信息。

如果您选择ModernCrypto instead of FIPSCrypto,则以上所有操作都将使用above完成。如果有人对此感到好奇,那么他们使用的确切加密是documented here

请注意,您必须使用PHP而不是SQL自己计算解密后的值。

毕竟,在将数据存储到数据库之前对其进行加密的全部意义在于将其对数据库服务器(以及任何可能危害该服务器的攻击者)隐藏起来。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52000755

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档