栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

使用 PBKDF2(和 Node.js)的对称密钥加密

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用 PBKDF2(和 Node.js)的对称密钥加密

使用 PBKDF2(和 Node.js)的对称密钥加密

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

这项研究要求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:tt",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。让我们试一试:

https://asecuritysite.com/node/node_encrypt2

对于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带来的落地机遇。敬请关注我们的微信公众号 “去中心化金融社区”。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/820687.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号