mysql 有什么类似 rsa 的加密手段么?

2022-04-22 00:41:08 +08:00
 cncmmdwl

我想管理能看到用户的密码,能接触的 sql 的人看不到,password 和 md5 都是单向加密的,aes 加密解密密匙都是一把不安全,有没有什么函数能实现对密码进行 rsa 加密,管理去数据库拿用户的 password 使用私钥解码用户的实际密码?

4141 次点击
所在节点    MySQL
57 条回复
GuangXiN
2022-04-22 14:16:24 +08:00
如果是为了用户登录为啥要用加密方案?单向哈希算法不好么?你就对用户的密码那么感兴趣么?
cncmmdwl
2022-04-22 15:07:25 +08:00
@3dwelcome 你理解错了,用户密码用类似 rsa 的加密后就不在解密,下一次验证密码用用户输入在 rsa 一次直接和数据库里的密文一比拉到
cncmmdwl
2022-04-22 15:08:38 +08:00
@ShallowAi 没办法,领导要啥我们就给啥,领导傻了我们也要跟着傻
cncmmdwl
2022-04-22 15:11:58 +08:00
@zhzy0077 你说的这个没有问题,老板的私钥生成后就送给领导保险箱里面,谁也别想拿出来,公钥云服务器上放着,甚至老板云服务器都没加密,只是要求老板能通过下载数据的方式反算密码,其他方式下无需解密
3dwelcome
2022-04-22 15:45:49 +08:00
@cncmmdwl "你理解错了,用户密码用类似 rsa 的加密后就不在解密,下一次验证密码用用户输入在 rsa 一次直接和数据库里的密文一比拉到"

正统的 RSA 每次加密后的结果都是不一样的。
3dwelcome
2022-04-22 15:49:14 +08:00
当然,RSA 解密后的结果肯定是一样的。这点也是为了提升安全性考虑。
shintendo
2022-04-22 15:51:59 +08:00
管理看了用户密码,拿去尝试登录其它网站?
3dwelcome
2022-04-22 16:03:53 +08:00
@shintendo 楼主说的只是片面之词,大部分老板都不懂技术的,谁关心什么密码原文。

也许真实需求可能刚好相反。是楼主作为技术员,想头盔一下老板的密码,登录一下老板的各种隐私账号。

老板账号密码,可要比普通用户的密码值钱多了。
swcat
2022-04-22 16:07:50 +08:00
两个字段, 一个是密码(可以用非对称加密加密一下), 一个是 bcrypt 处理过的 hash, 验证密码的时候调用 bcrypt 的 verify 方法
cncmmdwl
2022-04-22 16:35:06 +08:00
@3dwelcome 所以我想问问有没有这种非对称加密后密文还能是一样的?
cncmmdwl
2022-04-22 16:36:14 +08:00
@3dwelcome 不至于,有这想法直接去问就行了,公司都是亲属。
3dwelcome
2022-04-22 16:45:15 +08:00
@cncmmdwl "所以我想问问有没有这种非对称加密后密文还能是一样的?"

RSA 有两种运行模式,一种是签名,保证每次结果都和上一次一样。另一种是加密,由于加了 padding 随机数,结果都不一样更安全。

你可以用 RSA 签名模式,你这需求普通加密还不太一样。普通加密不需要对密文做二次对比。
Bromine0x23
2022-04-22 20:01:06 +08:00
虽然这个要求肯定有问题,但是可以换一个思路,把 RSA 填充用的随机数生成器换成一个返回固定值的生成器
cncmmdwl
2022-04-24 21:52:52 +08:00
@3dwelcome 我有一个想法,如果把密码签名后只留下签名,后面就用签名比对密码如何?
cncmmdwl
2022-04-24 21:53:37 +08:00
不对,这样子话就又变成单向了
hifumi
2022-04-30 12:31:36 +08:00
这个需求还是挺简单的,只要 RSA 加密时你不加盐值就可以了呀,RSA 就是一个乘方取模运算,下面的实现支持加密、验证和解密,密钥长度可以改,只要密码比密钥短就行了(如果需要支持密码比密钥长也可以修改一下下面的 demo ,实现分组加密)

```
from Cryptodome.PublicKey import RSA


def encrypt(public_key, password):
password = int.from_bytes(password, byteorder='big')
encrypted_password = pow(password, public_key.e, public_key.n)
return encrypted_password


def decrypt(private_key, encrypted_password, length):
decrypted = pow(encrypted_password, private_key.d, private_key.n).to_bytes(byteorder='big', length=length)
return decrypted


def verify_password(public_key, encrypted_password, password_to_be_verified):
return encrypted_password == encrypt(public_key, password_to_be_verified)


if __name__ == "__main__":
ras_key_length = 2 ** 10
private = RSA.generate(bits=ras_key_length)
public = private.publickey()

original_password = b"passwordpaordpasswordpasswordpasswordpasswordpasswordpasswordpasrdpasswordpasswordpassword"

print("Original password:", original_password)
encrypted = encrypt(public, original_password)

print("Encrypted password:", hex(encrypted))
print("Verification result:", verify_password(public, encrypted, original_password))

decrypted = decrypt(private, encrypted, ras_key_length // 8)
print("Decrypted password:", decrypted)
```

运行结果如下
```
Original password: b'passwordpaordpasswordpasswordpasswordpasswordpasswordpasswordpasrdpasswordpasswordpassword'
Encrypted password: 0x68334196df3d5c177e55e102f939ca2f0b2275e774159f0814921440161e5aad4e54076d13039f74733068dbad1d7c69e433a21b78f4ad485110bad0d45ff9b1ad5cf71a24ae16f14e53cd4b7f3d021f3a8b3e911f493da1339918c6e7bd9f23ef0f876a2142fd7f3de4556f64a7b12cb230f0c06a57571b6ad6ee1bfef85731
Verification result: True
Decrypted password: b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00passwordpaordpasswordpasswordpasswordpasswordpasswordpasswordpasrdpasswordpasswordpassword'
```
hifumi
2022-04-30 12:33:34 +08:00
MySQL 本身肯定是不支持类似功能的,当然也可以用存储过程来实现我刚刚发的 demo 的逻辑

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/848472

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX