首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Node.js密码密钥和iv与java SecretKeySpec / IvParameterSpec匹配

Node.js密码密钥和iv与java SecretKeySpec / IvParameterSpec匹配
EN

Stack Overflow用户
提问于 2015-05-31 07:53:13
回答 1查看 8.9K关注 0票数 5

我试图将Java (简单)加密算法移植到Node。我需要能够解密/加密来自Java端的加密/解密的内容。

我被困在一开始,密码的初始化。

在Java中,我用SecretKeySpec获得密钥,用IvParameterSpec获取初始化向量

代码语言:javascript
运行
复制
public CryptStuff(String password) throws zillion_exceptions {
    if (password==null) throw new InvalidKeyException("No encryption password is set!");
    key = new SecretKeySpec(password.getBytes("UTF-8"), "AES");
    cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    ivSpec=new IvParameterSpec(new byte[cipher.getBlockSize()]);
    cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
}

NodeJS需要一个密钥缓冲区和一个IV缓冲区,但是,我不知道如何从头计算它们:

代码语言:javascript
运行
复制
var mCrypto = require('crypto'),
    key=[0,0,0,0,0,0,.......],
    iv=[0,0,0,0,0,.........];

function init (password) {

    // generate key from password
    // generate IV from blocksize?

    var aesCipher = mCrypto.createCipheriv("aes-????????", (new Buffer(key)), (new Buffer(iv)));
    .
    .
    .
}

此外,AES/CBC/PKCS5Padd的匹配算法字符串是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-31 09:41:50

假设您的密码字符串与Java代码中的密码字符串相同,则可以在节点中创建如下所示的密钥缓冲区:

代码语言:javascript
运行
复制
var key = new Buffer(password, "utf8");

因为你用的是零填充静脉输液(坏!)在Java中,这是节点中的等效代码:

代码语言:javascript
运行
复制
var iv = new Buffer(16); // 16 byte buffer with random data
iv.fill(0); // fill with zeros

由于在Java中使用的是CBC模式,所以必须在节点中执行相同的操作。请注意,在选择密码字符串时,必须根据“密码”长度选择正确的密钥大小:

代码语言:javascript
运行
复制
var aesCipher = mCrypto.createCipheriv("aes-128-cbc", key, iv);
// or
var aesCipher = mCrypto.createCipheriv("aes-192-cbc", key, iv);
// or
var aesCipher = mCrypto.createCipheriv("aes-256-cbc", key, iv);

节点将自动应用PKCS#7填充,这与AES的PKCS#5填充相同。

密码不是钥匙!

密码通常没有合适的长度作为密钥(AES的有效长度为16字节、24字节和32字节),它仅由可打印的字符组成,这可能使攻击者更容易强暴密钥。

从密码创建密钥所需的是密钥派生函数。最受欢迎的是PBKDF2,bcrypt和scrypt (随着成本的增加)。

随机静脉注射!

你真的应该为你产生的每一个密文生成一个新的随机IV。如果您使用静态IV,则观察您的密文的攻击者可以确定您发送了相同甚至相似的消息。如果您使用的是随机IV,那么加密文本的差别很大,攻击者无法确定是否有两种不同的密文是从相同的明文创建的。这被称为语义安全。

随机IV本身不一定是秘密的,所以您可以很容易地将它添加到密文中,并在解密前将其分割掉。

您甚至可以将其与键派生函数(KDF)结合起来。只需为KDF生成一个随机盐即可。KDF通常能够派生出可变数量的输出字节,因此只需简单地让它导出key (串联),然后再拆分它们。现在,你只需要把盐加到密文上就行了。

认证!

根据您的系统,您可能容易受到攻击,例如填充oracle攻击。对此最好的防御措施是对密文进行认证。因此,您可以使用带有强MAC (如HMAC- So 256)的加密MAC方案,也可以使用经过身份验证的操作模式(如GCM或EAX )。Java和node都支持GCM,但是还需要做更多的工作。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30555101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档