sql - 生成加密安全 ID 而不是顺序身份/自动递增

标签 sql database cryptography

我已经有一段时间陷入这种困境,但找不到任何提示,尽管似乎有人已经做到了。

我需要用加密安全(即非连续!)ID 替换顺序 AUTO_INCREMENT(或等效)主键,但同时我想保持顺序 PK 的性能优势:保证未使用的下一个 ID,聚类性等

一个简单的方法似乎是实现一个密码伪随机置换生成器,以将 2^N 空间唯一地映射到 2^N,而不会发生冲突并使用初始化向量 (IV)。

虽然这可以在外部实现,但这确实需要存储和原子访问状态(排列位置或最后一个 id),这意味着在外部实现将非常低效(相当于运行后续的 UPDATE table SET crypto_id = FN_CRYPTO(autoincrement_id) WHERE autoincrement_id=LAST_INSERT_ID() 用于每个 INSERT)。

您是否知道在商业用途的数据库中有上述任何此类实现?

最佳答案

While this could be implemented externally, this does need to store and atomically access state (the permutation position or last id), which means implementing externally would be grossly inefficient (it's the equivalent of running a subsequent

 UPDATE table SET crypto_id = FN_CRYPTO(autoincrement_id) 
 WHERE autoincrement_id=LAST_INSERT_ID()

您可以使用生成的/虚拟的列来避免为每个插入运行建议的更新:

-- pseudocode
CREATE TABLE tab(
   autoincrement_id INT AUTO_INCREMENT,
   crypto_id <type> GENERATED ALWAYS AS (FN_CRYPTO(autoincrement_id)) STORED
);

-- SQL Server example, SHA function is an example and should be replaced
CREATE TABLE tab(
 autoincrement_id INT IDENTITY(1,1),
 crypto_id AS (HASHBYTES('SHA2_256',CAST(autoincrement_id AS NVARCHAR(MAX))))     PERSISTED
);

db<>fiddle demo


更多信息:


Dinu 编辑

如果您使用 SHA,请不要忘记将 secret 盐连接到 autoincrement_id;或者,您可以使用即 AES128 使用 secret 密码和 IV 加密 autoincrement_id

另外值得注意:任何有权访问表 DDL 的数据库用户都可以访问您的 secret 盐/ key /iv。如果您担心这一点,您可以使用参数化存储过程,即 FN_CRYPTO(id,key,iv),并将它们与每个插入一起发送。

要在应用端检索 crypto_id 而无需后续查询,您需要在应用端复制加密函数以在返回的 autoincrement_id 上运行。注意:如果使用 autoincrement_id 作为 AES128 的字节数组,请非常注意字节顺序,它可能与 DB 和应用程序端不同。唯一的选择是使用 mssql 的 OUTPUT 语法,但这是特定于 mssql 的,它需要运行 ExecuteScalar API 而不是 ExecuteNonQuery

关于sql - 生成加密安全 ID 而不是顺序身份/自动递增,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57085075/

相关文章:

sql - 在 postgres 中两个表之间的联接、聚合和转换

mysql - 在 select 和 from 子句中使用子查询出现 sql 错误

mysql 导入 csv 文件时 CSV 输入中的列计数无效

java - 对象化 GAE/J Google App Engine : Understanding asynchronous load

database - Laravel `orWhere()` 函数

sql - 如何通过对单个表的多个引用获取数据

java - 更改Cipher加密/解密模式,同时保留IV

python - 为什么我得到错误的 XOR 输出

c# - 在 .NET 中解密和检查签名时如何忽略系统存储?

sql - 嵌套查询以在表 B 中查找详细信息以获得表 A 中的最大值