javascriptrubyencryptionaessjcl

Decryption of AES created with sjcl.js in ruby


Hi so lets assume that client-side has a key that is not transfered via the same channel as the encrypted data.

What I am trying to accomplish is to decrypt the result of Stanford Javascript Crypto Library (sjcl) in ruby. or for a generalisation in any other language that has a crypto library that has support for AES.

Here is what I am doing in javascript:

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

And this is what I get in return:

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

So what I'm actually asking is, which of these parameters I need(assuming the server already has the "stack-password" key) in order to decrypt the secret server-side, and which library should I use? May be having AES decryption library is not enough?


Solution

  • For those coming here from Google, I managed to use the sjcl library to encrypt on Appcelerator's Titanium and decrypt on Ruby/Rails.

    Encrypt (javascript):

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

    The important bit is using a smaller IV.

    Decrypt (ruby):

    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