在ruby中使用sjcl.js创建的AES解密

时间:2012-11-26 11:25:37

标签: javascript ruby encryption aes sjcl

嗨,我们假设客户端有一个密钥不通过与加密数据相同的通道传输。

我想要完成的是解密ruby中Stanford Javascript Crypto Library (sjcl)的结果。或者用于具有支持AES的加密库的任何其他语言的泛化。

以下是我在javascript中所做的事情:

sjcl.encrypt('stack-password', 'overflow-secret')

这就是我得到的回报:

{
  "iv": "Tbn0mZxQcroWnq4g/Pm+Gg",
  "v": 1,
  "iter": 1000,
  "ks": 128,
  "ts": 64,
  "mode": "ccm",
  "adata": "",
  "cipher": "aes",
  "salt": "pMQh7m9Scds",
  "ct": "H6JRpgSdEzKUw2qEO1+HwIzAdxGTgh0"
}

所以我实际要问的是,我需要哪些参数(假设服务器已经有“stack-password”密钥)才能解密秘密服务器端,我应该使用哪个库? 可能有AES解密库是不够的?

3 个答案:

答案 0 :(得分:9)

以下不能协商一段时间(或硬编码)。

  • ct:密码加密数据,显然是
  • iv:初始化向量,应该是唯一的,不能与AES-CCM
  • 使用相同的密钥重复使用
  • salt:随机,用于通过密码Pbkdf2创建密钥
  • adata:其他经过身份验证的数据是您要包含的纯文本数据,但请确保在使用AES-CCM时未将其篡改。如果您不打算包含任何数据,那么您可以忽略它(您必须使用sjcl中的明文传递它。)

以下你可以协商一个时间段(或硬编码),实际上你不应该在服务器加密api中插入这些值,当传输时未经身份验证并期待安全性。 adata viterks如果您希望基于客户端可以更改<{p}},则iter不会是个不错的地方

  • ksPbkdf2的迭代,这只需要足够高,以减慢您的密码的暴力需要随着未来的硬件速度而变化。
  • ts:密码以了解使用Pbkdf2生成的密钥大小,需要随着未来的安全数量而变化
  • cipher:使用tagsize了解验证标记的大小是密文的一部分
  • mode:如果您只支持AES,那么您可以假设。
  • v:如果您只支持AES-CCM而不是假设。
  • AES-128-CCM:如果你将来只支持一个版本的sjcl,那么你可以假设。

使用OpenSSL library使用ruby似乎只要您的OpenSSL支持puts OpenSSL::Cipher.ciphers {{1}}进行检查,它就可以正常工作。它确实支持generating keys using pbkdf2,但你需要使用Sha256摘要与sjcl兼容,而sjcl又取决于你的openssl版本。

答案 1 :(得分:3)

对于那些来自Google的人,我设法使用sjcl库加密Appcelerator的Titanium并在Ruby / Rails上解密。

加密(javascript):

var data = SJCL.encrypt('your key here', 
                        'plain text', 
                        { mode: 'gcm', 
                          iv: SJCL.random.randomWords(3, 0) });

重要的是使用较小的IV。

解密(红宝石):

def self.decrypt(h)
  h = HashWithIndifferentAccess.new(JSON.parse(h))

  key = OpenSSL::PKCS5.pbkdf2_hmac('your key here', Base64.decode64(h[:salt]), 1000, h[:ks]/8, 'SHA256')

  puts "Key: #{key.unpack('H*')}"

  puts "Salt: #{Base64.decode64(h[:salt]).unpack('H*')}"

  c = OpenSSL::Cipher.new("#{h[:cipher]}-#{h[:ks]}-#{h[:mode]}")

  c.decrypt

  c.key = key

  c.iv = Base64.decode64(h[:iv])

  puts "IV: #{Base64.decode64(h[:iv]).unpack('H*')}"

  c.auth_data = ""

  c.update(Base64.decode64(h[:ct]))
end

答案 2 :(得分:1)

或者,我将SJCL的翻译写入纯Ruby(至少对于CCM部分)。这并不需要更新OpenSSL,但速度有点慢。

您可以在https://github.com/mdp/sjcl_rb

找到它

希望这有帮助