【问题标题】:Performing AES Encryption is Ruby compared to Javascript与 Javascript 相比,执行 AES 加密是 Ruby
【发布时间】:2017-08-31 03:57:41
【问题描述】:

我在这部分代码上苦苦挣扎,我需要在我的服务器端(Ruby)上从客户端解密 AES。我知道所有信息,但我正在努力重新生成加密。

我目前正在使用来自https://github.com/brix/crypto-jsCryptoJS。我不确定它使用的是哪个版本的 AES,这可能是我的第一个问题。

我目前如何在 Javascript 中加密我的数据的一个例子是:

encodeURIComponent(CryptoJS.AES.encrypt("Message","Key").toString())

现在我正在 Ruby 中使用 opensslcgi 来尝试解密。这是错误的并且不起作用,但我想展示我正在尝试的内容,因为我相信它很接近。我不明白如何在加密中使用密钥,但我正在按照我找到的示例进行操作 here

require "openssl"
require "cgi"

cipher = OpenSSL::Cipher.new('AES-128-CBC')
cipher.encrypt
key = "Key"
iv = cipher.random_iv

encrypted = cipher.update("Message") + cipher.final

puts CGI::escape(encrypted.to_s)

我刚刚将"Message""Key" 设置为不共享我的信息,在安全性和密码学方面我是个业余爱好者,但我已经用较低级别的语言完成了这些事情而没有问题。我认为问题发生在两个主要方面

  1. 我对这些高级语言的工作原理以及我正在使用的库缺乏了解
  2. 这些语言中的字符串有时是 UTF-8 与 UTF-16,因此将 "Message" 作为字符串传递可能会导致问题

在 JAVASCRIPT 中加密和解密的完整示例:

使用输入 1 进行加密和 URL 编码:

encodeURIComponent(CryptoJS.AES.encrypt("1","Key").toString())

结果:

"U2FsdGVkX19Lp8ItQaO5h6Lj68sheHeYrIkJAfqt1Tw%3D"

解码 URL 和解密:

CryptoJS.AES.decrypt(decodeURIComponent("U2FsdGVkX19Lp8ItQaO5h6Lj68sheHeYrIkJAfqt1Tw%3D"), "Key").toString(CryptoJS.enc.Utf8)

结果:

"1"

【问题讨论】:

  • 您至少可以发布可以使用测试密钥和消息运行的代码,对吧?您的 URL 编码/解码在哪里?我们不是来做你的工作的。
  • 您在 CryptoJS 中的 "Key" 不是真正的密钥。它是用于派生密钥的密码。据我了解 Ruby 中的 OpenSSL 包装器,情况并非如此。两个代码sn-ps是完全不同的。如果 CryptoJS 代码可以更改(是吗?),答案会很简单。为什么要在浏览器中进行对称加密。它没有提供比 HTTPS 更高的安全性。
  • 如果您只使用对称加密,您需要在服务器和客户端使用完全相同的密钥。如果您将加密密钥从服务器发送到客户端或其他方式,您需要加密您的对称加密密钥。最简单的方法是使用 TLS。如果你使用 TLS,那么数据和密钥都是加密的,所以你不需要自己加密。这不提供任何安全性,只是有点混淆。你应该阅读:nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/…
  • 您是否考虑过使用像 RNCryptor 这样的库,它可以安全地实现 Ruby、JavaScript 和其他几种语言?
  • 我将它用作一个简单的屏障。消息没那么重要。我只是想使用它来创建独特的 url,其中包含不容易看到的数据点。我可以只使用编码,但喜欢有密码这一事实,即使按部门和页面分隔某些客户端代码访问是不安全的。

标签: javascript ruby encryption cryptography aes


【解决方案1】:

Artjom B 在上面的评论中指出了您的至少一个问题,这是尝试让 crypto-js 与其他库互操作时经常遇到的问题:crypto-js 没有接受“密钥”您使用它的方式,而不是密码。密码不是钥匙!!!

在内部,crypto-js 使用非常糟糕的算法将密码转换为密钥。该算法很差有两个原因:(1) 它基于不安全的 MD5,以及 (2) 将密码转换为密钥应该是一个缓慢的过程,以阻止对密码的暴力猜测。在crypto-js中,这个过程并不慢。

为了让你朝着正确的方向前进,请不要打电话:

CryptoJS.AES.encrypt("Message","Password") 

改为调用

CryptoJS.AES.encrypt("Message", key, { iv: iv });

您可能还需要探索填充以使其与 Ruby 互操作。

【讨论】:

  • 谢谢,我会试试这个!这应该类似于我正在运行的 Ruby 代码还是那里也有错误。
  • @napkinsterror 我不是 ruby​​ 专家,但我看到的 ruby​​ 唯一潜在问题是 AES 密钥根据定义是 16、24 或 32 字节之一。我不知道当你传递更小的东西时 ruby​​ 在引擎盖下做了什么:也许它用 0 填充它。要记住的一件事是,用于加密的同一 IV 也应该用于解密。 IV 不是秘密的,通常放在密文的开头,以便接收端可以在开头读取它以进行解密。
猜你喜欢
  • 2015-11-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-19
  • 2015-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多