Расшифровка AES, созданного с помощью sjcl.js в ruby
Привет, давайте предположим, что на стороне клиента есть ключ, который не передается по тому же каналу, что и зашифрованные данные.
То, что я пытаюсь сделать, - это расшифровать результат Stanford Javascript Crypto Library (sjcl) в ruby. или для обобщения на любом другом языке, который имеет криптографическую библиотеку, которая поддерживает 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 недостаточно?
3 ответа
Для тех, кто пришел сюда из Google, мне удалось использовать библиотеку sjcl для шифрования на Applelerator's 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
Следующее не может быть предметом переговоров (или жестко закодировано).
ct
: шифруйте текст зашифрованными данными, очевидноiv
: вектор инициализации, должен быть уникальным и не использоваться повторно с тем же ключом для AES-CCMsalt
: random, и используется для создания ключа из пароля с помощью Pbkdf2adata
: дополнительные аутентифицированные данные - это текстовые данные, которые вы хотите включить, но убедитесь, что они не были подделаны при использовании AES-CCM. Если вы никогда не собираетесь включать какие-либо данные, вы можете игнорировать их (вам пришлось бы передавать их с открытым текстом в sjcl).
Далее вы можете договориться о времени (или жестко запрограммировать), фактически вы не должны вставлять эти значения в API шифрования сервера при передаче без проверки подлинности и ожидать безопасности. adata
не будет плохим местом для v
, iter
, или же ks
если вы хотите, чтобы он был изменяемым в зависимости от клиента
iter
Итерации для Pbkdf2, это просто должно быть достаточно высоко, чтобы замедлить грубую обработку вашего пароля в будущем со скоростью аппаратного обеспечения.ks
: keysize, чтобы знать, какой размер ключа генерируется с помощью Pbkdf2, должен меняться в зависимости от степени безопасности в будущемts
: tagize, чтобы знать, какой размер тега аутентификации является частью вашего зашифрованного текстаcipher
: Если вы будете поддерживать только AES, то вы можете просто предположить.mode
: если вы будете поддерживать только AES-CCM, чем вы можете предположить.v
: Если вы будете поддерживать только одну версию sjcl в будущем, вы можете просто предположить.
При использовании ruby библиотека OpenSSL может работать до тех пор, пока ваш OpenSSL поддерживает AES-128-CCM
puts OpenSSL::Cipher.ciphers
Проверять. И он поддерживает генерацию ключей с использованием pbkdf2, но вам нужно использовать дайджест Sha256, чтобы быть совместимым с sjcl, что опять-таки зависит от вашей версии openssl.
В качестве альтернативы я написал перевод SJCL на чистый Ruby (по крайней мере для частей CCM). Это не требует обновления OpenSSL, но это немного медленнее.
Вы можете найти его на https://github.com/mdp/sjcl_rb
Надеюсь это поможет