6

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

我想要完成的是在 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"
}

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

4

3 回答 3

9

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

  • ct: 密文你的加密数据,很明显
  • iv:初始化向量,应该是唯一的,并且不能与AES-CCM的相同密钥重用
  • salt:随机,用于使用Pbkdf2从密码创建密钥
  • adata: 额外的认证数据,是你想要包含的纯文本数据,但要确保它在使用AES-CCM时没有被篡改。如果您永远不会包含任何数据,那么您可以忽略它(您必须将它与 sjcl 中的明文一起传递)。

以下您可以协商一个时间头(或硬编码),实际上您不应该将这些值插入服务器加密 api,当未经身份验证传输并期望安全时。对于,或者如果您希望它可以根据客户进行更改,adata这不是一个坏地方viterks

  • iter: Pbkdf2的迭代,它只需要足够高以减慢密码的暴力破解需要在未来随着硬件速度的变化而变化。
  • ks: keysize 知道用Pbkdf2生成什么大小的密钥,需要随着未来的安全量而改变
  • ts: tagsize 知道什么大小的身份验证标签是密文的一部分
  • cipher:如果您只支持AES,那么您可以假设。
  • mode:如果您只支持AES-CCM,那么您可以假设。
  • v:如果您将来只支持一个版本的 sjcl,那么您可以假设。

只要您的 OpenSSL 支持检查,使用OpenSSL 库的 ruby​​ 似乎就可以工作。AES-128-CCM puts OpenSSL::Cipher.ciphers它确实支持使用 pbkdf2 生成密钥,但您确实需要使用 Sha256 摘要才能与 sjcl 兼容,这又取决于您的 openssl 版本。

于 2012-11-26T17:37:13.427 回答
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
于 2014-12-03T23:55:54.527 回答
1

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

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

希望这可以帮助

于 2014-03-17T01:27:49.407 回答