Encryption 隐藏敏感信息的最简单方法

Encryption 隐藏敏感信息的最简单方法,encryption,Encryption,隐藏敏感标识符的最简单方法是什么,同时提供一些从外部识别数据的等效方法 例如,假设我有一个包含记录的数据库表,其中一个是敏感ID字段 ID 2A 1S etc... 然后我想要第二张唱片: ID PublicID 2A AXXX44328 1S KKKZJSAAS 这样,当我得到一个PublicID时,我总能确定它所指的ID: H(PublicID) = ID 但没有其他人能够做到这一点 还要注意,我希望能够在至少两个不同的位置复制字符串。因此,如果我有两个服务器/数据库

隐藏敏感标识符的最简单方法是什么,同时提供一些从外部识别数据的等效方法

例如,假设我有一个包含记录的数据库表,其中一个是敏感ID字段

ID
2A
1S
etc...
然后我想要第二张唱片:

ID    PublicID
2A    AXXX44328
1S    KKKZJSAAS
这样,当我得到一个PublicID时,我总能确定它所指的ID:

H(PublicID) = ID
但没有其他人能够做到这一点

还要注意,我希望能够在至少两个不同的位置复制字符串。因此,如果我有两个服务器/数据库,那么ID 2A必须分别映射到其中每个服务器/数据库上的字符串AXX44328


我怀疑这就像是加密——扔掉一个公钥?

生成某种随机的、唯一的字符串并将其作为公共ID存储在数据库中就足够了。在公共ID上对表进行索引,您可以轻松地检索给定公共ID的真实ID(和其他行值)。因为数据库是私有的,没有人能计算出给定公共ID的ID

生成随机唯一字符串的一种简单方法是采用真实ID+某个salt值的散列(例如SHA-1),例如

my $public_id = sha1( $salt . $id );
$salt
值应该是一个长的随机字符串,只生成一次,保存在服务器上,从不公开。这使得攻击者很难(几乎不可能)通过强制哈希从公共ID反向工程真实ID(如果ID很短且是数字的,则不使用salt非常容易)

这种方法的优点是,只要$salt值保持不变,相同的$id将始终映射到相同的$public_id



如果这不是一个选项,则生成一个随机密钥并用它加密真实ID,然后将加密版本用作公共ID。您可以稍后解密此ID以获取真实ID。

您没有指定编程语言。下面是一个PHP示例,与RJH建议的SHA1类似,但使用了适当的对称加密算法,而不是SHA1,从而消除了(甚至是远程)冲突的可能性:

define('KEY', 'S4mPhZg3rQga'); function encrypt($text) { return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, KEY, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))); } function decrypt($text) { return mcrypt_decrypt(MCRYPT_RIJNDAEL_256, KEY, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)); } // example usage: $C = encrypt('1234'); echo("Public ID: $C\n"); $P = decrypt($C); echo("Private ID: $P\n"); 定义('KEY','S4mPhZg3rQga'); 函数加密($text) { 返回base64_encode(mcrypt_encrypt(mcrypt_RIJNDAEL_256,KEY,$text,mcrypt_MODE_ECB,mcrypt_create_iv)(mcrypt_get_iv_size(mcrypt_RIJNDAEL_256,mcrypt_MODE_ECB),mcrypt_RAND)); } 函数解密($text) { 返回mcrypt_decrypt(mcrypt_RIJNDAEL_256,密钥,base64_decode($text),mcrypt_MODE_ECB,mcrypt_create_iv(mcrypt_get_iv_size(mcrypt_RIJNDAEL_256,mcrypt_MODE_ECB),mcrypt_RAND)); } //用法示例: $C=加密('1234'); echo(“公共ID:$C\n”); $P=解密($C); echo(“私有ID:$P\n”);
密钥的值应设置一次,在两台服务器中的值相同,并且永远不应显示。显示数据时使用encrypt(),接受外部数据时使用decrypt()。不需要实际存储PublicID,只需动态计算即可。

如果您的ID相对较短(15字节或更少),则我建议使用分组密码对其进行加密,即。AES使用长度为128、192或256位(128位足够)的密钥K。由于AES只处理16个字节的数据块,因此您必须稍微填充ID。“常用”填充(称为“PKCS#5”)包括添加n个字节(n>=1),所有字节的值均为n,因此生成的长度是合适的(此处,您希望长度为16)

因此,将ID(敏感数据)转换为S(可以向公众显示的加扰字符串)是:S=AESencrypt_K(pad(ID))。反向操作是:ID=unpad(aesdeccrypt_K(S))。如果ID为16字节或更多,则加密将使用AES的多个调用,这些调用如何链接在一起存在一些微妙之处。关键词是链接模式,通常的答案是“CBC”

这两个操作都需要知道密钥K(相同的K)。这意味着任何可以从ID计算S的人也可以从S计算ID,反之亦然


现在,如果您需要一些实体能够从ID计算S,而不给它们进行反向操作的能力,那么事情就更复杂了。特别是,您不能有一个确定的过程:如果有一个S可以从ID计算出来,那么任何人都可以尝试对ID的可能值进行穷举搜索,直到找到与给定S的匹配。所以你必须放松这个模型,因为一个给定的ID可能会产生大量可能的加扰字符串S',这样所有这些S'可能会被拥有“正确”秘密值的人转换回ID。这是从非对称加密中得到的。通常的非对称加密算法是。对于1024位RSA密钥(适当安全性的典型大小),ID的大小可以达到117字节,S'的长度将为128字节(大小的增加对应于注入的随机数据,这使得进程不确定)。如果128字节太多,您可以通过椭圆曲线上的El Gamal加密获得较短的加密消息(对于最多20字节的ID,可以减少到大约40字节),但您可能很难找到现有的实现。

因为您希望能够在两个断开连接的,然后,您需要有某种共享密钥

这是一个完美的地方。通过维基百科窃取:

Let:
H(·)是一个加密哈希函数
K是一个密匙,在哈希函数的块大小的右边加上额外的零
m是要验证的消息
∥ 表示串联
⊕ 表示异或(XOR)
opad是外部填充(0x5c…5c5c,一个块长的十六进制常量)
ipad可以是内部填充(0x3636…3636,一个块长的十六进制常量)

那么HMAC(K,m)的数学定义是
HMAC(K,m)=H((K⊕ (opad)∥ H
>>> import hmac
>>> hmac.new(key='abc123secret make me long', msg='This is my unique key #1')
<hmac.HMAC instance at 0xb77bdbac>
>>> _.hexdigest()
'c23a224afa917d13fbef58ee14884269'