

波恩大学研究人员最近发表的一篇论文表明,许多开发者都在努力解决如何正确保护密码。

这项研究要求Freelance.com的260名Java开发人员编写能够安全存储密码的代码。最后,他们中的43人开始了这项工作。给定的任务是为一个虚假的社交媒体网站设置一个用户注册系统。其中39个是男性,1个是女性,其他人没有明确性别。37人有大学学历,平均有6.4年的Java编程经验:

为了评估在任务中获得更多报酬是否会提高安全性,小组中大约一半的人得到了100欧元,其余的人得到了200欧元。然后把他们按照是否提示他们使用给定的方法的分类方式进行分类:
- 使用定义密码存储方法(P100),支付100欧元。
- 使用定义密码存储方法(P200),支付200欧元。
- 未定义密码存储方式(N200),支付200欧元。
- 未定义密码存储方式(P200),支付200欧元。
通常情况下,开发人员需要3天左右的时间提交他们的工作,其中18人不得不重新提交他们的代码,因为他们使用的是明文密码。其中15个给出的理由是,规范中没有对安全密码存储提出要求,而其他3个只是重新提交了相同的明文密码。

最后,从安全性的角度来看,结果很糟糕,许多开发人员使用编码格式(Base64)、弱哈希(MD5和SHA-1)和弱密码加密(AES和3DES):

令人担忧的是,将近五分之一的人选择了一个甚至不是哈希方法的方法:Base64。Base64的安全性是零,因为它是一种编码方法。密码的哈希和以加扰形式的编码之间经常被混淆。对于那些使用Base64的人,说辞是:
- 对其进行加密,使清晰的密码不可见
- 很难解密
总的来说,研究人员发现,开发人员通常不知道哈希和加密之间的区别。当要对密码进行“盐化”时,43人中只有15人选择了“盐化”,而这43人中有17人从其他网站复制了代码。研究人员还发现,给开发人员更多的报酬并不能产生更好的代码。该研究还强调出,对加密和哈希的知识掌握普遍还不是很好,许多人无法区分这两者。
所以让我们自己保护密码。
保护密码的一种方法是进行加密,并使用一种慢速哈希方法,如PBKDF2。我们会发现PBKDF2是用来保护wi-fi系统密码的方法。所以让我们使用Node.js来进行一系列加密算法使其最终实现加密,然后根据密码、盐值和给定的哈希方法来生成加密密钥:
const crypto = require("crypto"); var message="Hello"; var algorithm="aes-128-cbc"; var password="qwerty"; var hash="sha256"; var salt="salt"; var args = process.argv; if (args.length>2) message=args[2]; if (args.length>3) algorithm=args[3]; if (args.length>4) password=args[4]; if (args.length>5) hash=args[5]; if (args.length>6) salt=args[6]; var key=crypto.randomBytes(16); var iv = crypto.randomBytes(16); var err=null; keysize=16; if (algorithm.indexOf("256")>-1) { keysize=32; } if (algorithm.indexOf("cha")>-1) { keysize=32; } if (algorithm.indexOf("bf")>-1) { iv = crypto.randomBytes(8); } if (algorithm.indexOf("cast")>-1) { iv = crypto.randomBytes(8); } if (algorithm.indexOf("des-")>-1) { iv = crypto.randomBytes(8); keysize=8; } if (algorithm.indexOf("ecb")>-1) { iv = null; } crypto.pbkdf2(password, salt, 100, keysize, hash, (err, key) => { const cipher = crypto.createCipheriv(algorithm, Buffer.from(key),iv); let encrypted = cipher.update(message); encrypted = Buffer.concat([encrypted, cipher.final()]); const decipher = crypto.createDecipheriv(algorithm, Buffer.from(key),iv); let decrypted = decipher.update(encrypted); decrypted = Buffer.concat([decrypted, decipher.final()]); console.log("Message: ",message); console.log("\nEncryption Algorithm: ",algorithm); if (iv!=null) console.log(" IV:\t",iv.toString('hex')); console.log("\nPassword:\t",password); console.log(" Hashing:\t",hash); console.log(" Salt:\t\t",salt); console.log("\nDerived Key:\t",key.toString('hex')); console.log("\nEncrypted:\t",encrypted.toString('hex')); console.log("Encrypted:\t",encrypted.toString('base64')); console.log("\nDecrypted:\t",decrypted.toString()); });
在这种情况下,为了生成密钥,我们使用回调函数,调用PBKDF2函数,然后当它完成时,回调括号中定义的代码:
crypto.pbkdf2(password, salt, 100, keysize, hash, (err, key) => {...}
在本例中,我们传递了一个密码、一个盐值和一个哈希方法。我们可以使用的一些典型哈希方法包括:

因此,对于密码为“qwerty”,哈希方法为“SHA-1”,盐值为“salt123”,我们得到以下16字节的键:
Password: qwerty Hashing: sha1 Salt: salt123Derived Key: 8b8c9613f705303540f4f52cd4393b0f
密钥的大小显然取决于我们想要使用的加密方法,因此128位密钥需要16个字节,256位密钥需要32个字节。keysize的值被传递给函数:
crypto.pbkdf2(password, salt, 100, keysize, hash, (err, key) => {...}
现在我们需要选择加密方法。在大多数情况下,我们将使用AES或ChaCha20,但还有很多选择:

为此,在Node.js中,我们的每个方法都有一个标签,例如“AES -256- CBC”,用于CBC模式的256位AES。让我们试一试:
对于128位AES-CTR:
Message: TestEncryption Algorithm: aes-128-ctr IV: d8e6e5de3d11ab945595c2297a406ee4Password: qwerty Hashing: sha1 Salt: salt123Derived Key: 8b8c9613f705303540f4f52cd4393b0fEncrypted: 74247bc0 Encrypted: dCR7wA==Decrypted: Test
对于256位AES OFB:
Message: TestEncryption Algorithm: aria-256-ofb IV: 4f7f8ccd91279504377745fa10cbdfc9Password: qwerty Hashing: sha1 Salt: salt123Derived Key: 8b8c9613f705303540f4f52cd4393b0f9298aee6eadc3c41960b0301b019aca3Encrypted: a4be0b31 Encrypted: pL4LMQ==Decrypted: Test
加密和解密部分,我们基本上是先加密一个字符串(消息),然后用以下方法解密密文:
const cipher = crypto.createCipheriv(algorithm, Buffer.from(key),iv);
let encrypted = cipher.update(message); encrypted = Buffer.concat([encrypted, cipher.final()]);
const decipher = crypto.createDecipheriv(algorithm, Buffer.from(key),iv);
请注意,加密密钥的大小是 256 位版本的两倍,是 128 位密钥大小的两倍。
Source:https://medium.com/@billatnapier/symmetric-key-encryption-with-pbkdf2-and-node-js-846ac57901c1
关于
ChinaDeFi – ChinaDeFi.com 是一个研究驱动的DeFi创新组织,同时我们也是区块链开发团队。每天从全球超过500个优质信息源的近900篇内容中,寻找思考更具深度、梳理更为系统的内容,以最快的速度同步到中国市场提供决策辅助材料。
Layer 2道友 – 欢迎对Layer 2感兴趣的区块链技术爱好者、研究分析人与Gavin(微信: chinadefi)联系,共同探讨Layer 2带来的落地机遇。敬请关注我们的微信公众号 “去中心化金融社区”。
