Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 用ruby加密数据用node解密_Javascript_Ruby_Encryption_Node.js_Cryptography - Fatal编程技术网

Javascript 用ruby加密数据用node解密

Javascript 用ruby加密数据用node解密,javascript,ruby,encryption,node.js,cryptography,Javascript,Ruby,Encryption,Node.js,Cryptography,我想在ruby应用程序中加密一些数据,然后在nodejs应用程序中对其进行解码。我一直在努力让这项工作,现在我只是想用两种语言加密同一段数据,以获得相同的结果,但我似乎无法做到这一点 //js var crypto = require('crypto'); var key = crypto.createHash('sha1').update('key').digest('hex'); console.log(key); // a62f2225bf70bfaccbc7f1ef2a39783671

我想在ruby应用程序中加密一些数据,然后在nodejs应用程序中对其进行解码。我一直在努力让这项工作,现在我只是想用两种语言加密同一段数据,以获得相同的结果,但我似乎无法做到这一点

//js
var crypto = require('crypto');

var key = crypto.createHash('sha1').update('key').digest('hex');
console.log(key); // a62f2225bf70bfaccbc7f1ef2a397836717377de

var encrypted = "";
var cipher = crypto.createCipher('bf-cbc', key);

encrypted += cipher.update('text');
encrypted += cipher.final('hex');

console.log(encrypted); //outputs 4eafd5542875bd3c
看起来我从编码中得到了一个十六进制字符串

#ruby
require 'openssl'
require 'digest/sha1'
c = OpenSSL::Cipher::Cipher.new("bf-cbc")
c.encrypt
# your pass is what is used to encrypt/decrypt
c.key = key = Digest::SHA1.hexdigest("key")
p key # a62f2225bf70bfaccbc7f1ef2a397836717377de
e = c.update("text")
e << c.final
p e # 皋?;??
#ruby
需要“openssl”
需要“摘要/sha1”
c=OpenSSL::Cipher::Cipher.new(“bf cbc”)
c、 加密
#你的通行证是用来加密/解密的
c、 key=key=Digest::SHA1.hexdigest(“key”)
p键#A62F2225BF70BFACCBC7F1EF2A39783677DE
e=c.更新(“文本”)

e您的密码文本将是一些看起来随机的字节。这些字节可以用十六进制、Base64或其他方式表示。看起来您的ruby代码正在输出原始字节。我建议您将这些原始字节转换为十六进制以进行比较

查看您的代码,您还应该将河豚(“bf”)更改为AES。Blowfish具有64位块大小,现在已过时


您最好明确指定填充,PKCS7是常见的

有几个微妙的因素导致此操作失败。最重要的一点是,您没有在代码中指定IV,因此将为您生成一个随机值。您会注意到,您甚至无法用这种方式在同一种编程语言中解密密文

因此,您需要为这两种实现提供显式的IV。但在我向您展示代码之前,有一些建议:

密钥生成

Blowfish在64位块上运行,其密钥大小各不相同,但OpenSSL(目前支持Ruby和node.js的密码实现)默认使用128位,即16字节

因此,您的密钥违反了两个原则-第一:它太长了。它是SHA-1散列的十六进制表示,它是20字节*2=40字节,而不是16字节。大多数情况下,这很好,因为实现会适当地截断值,但这是您不应该依赖的

第二个错误,更严重的是,您使用十六进制表示而不是原始字节:大安全问题!十六进制字符根本不是随机的,因此实际上可以将输入的熵减少到长度的一半(因为底层字节是随机的)

生成随机密钥的安全方法是使用OpenSSL::random

key = OpenSSL::Random.random_bytes(cipher_key_len)
第三个错误是将密钥硬编码在源代码中。这是个坏主意。您至少应该将其存储在文件系统中的其他位置,因为访问受到严格限制。另请参见另一个问题。密钥应存储在带外,并且仅在应用程序内动态加载

密码

河豚变老了。它仍然被认为是完整的,因为暴力强迫它是打破它的唯一方式。但2^64的搜索空间并不是足智多谋的攻击者无法达到的。因此,您确实应该转到AES

填充

默认情况下,使用PKCS5Padding(也称为PKCS7Padding)的OpenSSL焊盘。Ruby从中获益,我敢打赌node.js也利用了这一点——所以你应该在这方面很安全

现在来看看有效的解决方案。我们需要生成一个IV,Blowfish要求它是64位8字节。您将需要rbytes来获取节点中的安全随机数。IV可能在您的来源中硬编码(它是公共信息,不影响安全)-但双方必须相同。您应该预生成一个值,并将其用于node.js和Ruby

/*node.js*/

var rbytes = require('rbytes');
var iv = rbytes.randomBytes(8);

/*see advice above - this should be out-of-band*/
var key = rbytes.randomBytes(16);
var encrypted = "";
var cipher = crypto.createCipheriv('bf-cbc', key, iv);

encrypted += cipher.update('text');
encrypted += cipher.final('hex');
现在是Ruby部分:

require 'openssl'

c = OpenSSL::Cipher::Cipher.new("bf-cbc")
c.encrypt
# should be out-of-band again
c.key = OpenSSL::Random.random_bytes(16)
# may be public but has to be the same for Ruby and node
iv = OpenSSL::Random.random_bytes(8)
c.iv = iv 
e = c.update("text")
e << c.final
puts e.unpack('H*')[0]
需要“openssl”
c=OpenSSL::Cipher::Cipher.new(“bf cbc”)
c、 加密
#应该是带外了
c、 key=OpenSSL::Random.Random_字节(16)
#可以是公共的,但对于Ruby和node必须相同
iv=OpenSSL::Random.Random_字节(8)
c、 iv=iv
e=c.更新(“文本”)

eOK。我要感谢所有帮助我的人。基本上,这个帖子回答了我的问题:。我将继续并发布这两个程序,以防其他人不得不通过这个繁琐的程序。请记住,这并不意味着绝对安全,这是ruby加密数据和节点解密数据的垫脚石。你必须采取更多的措施来确保采取更高的安全措施

代码位于以下要点:


它们在ruby 1.9.2p290和节点0.4.10上运行,在ruby 1.8.7输出中运行\347\232\213\006\250\207\302,而1.9.2输出\xE7\x9A\x8B\x06\xA8\x87\xC2It是e.unpack('H*'),但节点加密和ruby加密的值当然不相等。如果仍然不匹配,请检查每个版本使用的填充。正如我所说的,最好明确地说明它。一般来说,这是一个很好的建议。但是,我建议加密生成一个IV并将IV前置到密文,这样输出看起来像
“#{IV raw bytes}#{cipherth raw bytes}”
。解密应该知道IV的大小,并将该大小输入的第一个块作为IV,其余部分为密文。这样,IV在每次加密时都是随机的,正如预期的那样。请注意,当每个加密消息都有自己的IV时,IV不是秘密,因此向公众共享单个消息的IV是安全的。在这种情况下,唯一的秘密就是钥匙。这是一个很好的方法,正义。但是它更复杂,所以我倾向于这样解释..你应该在你的密码上调用#encrypt或#decrypt作为第一个操作-请看。我想我是用encrypt.rb第10行的send(mode)来做的,除非我不理解你说的正确无问题。虽然我自己的答案可能对某些人来说并不令人满意(出于某种原因),但它确实起到了应有的作用,因此我必须将其标记为“答案”