railssaml如何解密xml?

rails saml how to decrypt xml?

我正在进行 SAML 身份验证,当我收到 xml 时,其中一部分已加密。这是我需要的部分(包含姓名、电子邮件等)

为此我有一个私钥来解密它,但我不知道该怎么做。

我在这里:

    response  =  OneLogin::RubySaml::Response.new(params[:SAMLResponse])
    response.settings = set_settings
    doc = Nokogiri::XML(response.response)
    document = XMLSecurity::Document.new(doc)
    ### NOT USED HERE
    formated_cert = OneLogin::RubySaml::Utils.format_cert(CONFIG_CERTIFICATE)
    cert = OpenSSL::X509::Certificate.new(formated_cert)
    formated_private_key = OneLogin::RubySaml::Utils.format_private_key(CONFIG_PRIVATE_KEY)
    private_key = OpenSSL::PKey::RSA.new(formated_private_key)
    ### NOT USED HERE
   ret = doument.decrypt!(settings) rescue nil # PROBLEME HERE, DONT WORK


 def set_settings
  settings = OneLogin::RubySaml::Settings.new
  ...
 settings.security[:digest_method]    = XMLSecurity::Document::SHA1
 settings.security[:signature_method] = XMLSecurity::Document::SHA1   
  ...
  settings.certificate = CONFIG_CERTIFICATE
  settings.private_key = CONFIG_PRIVATE_KEY

end

所以,ret应该是我可以使用的解密xml,但它总是停留在nilrescue nil,以避免500)

我用OneLogin::RubySamlXMLSecurity

但我不知道自己做错了什么,

有人吗?

终于,我成功解决了这个问题: 解决方法在这里:

  response.settings = saml_settings

  enc_key = REXML::XPath.first(response.document, "//xenc:EncryptedKey//xenc:CipherData/xenc:CipherValue").text
  enc_value = REXML::XPath.first(response.document, "//xenc:EncryptedData/xenc:CipherData/xenc:CipherValue").text
  private_key = OpenSSL::PKey::RSA.new(CONFIG_PRIVATE_KEY)
  data_key = private_key.private_decrypt(Base64.decode64(enc_key), OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)

  actual_output = decrypt_cipher_data(data_key, enc_value)


 clean_output = actual_output.slice(0..(actual_output.index('</Assertion>') + '</Assertion>'.length-1))

所以clean_output就是最后的xml解密,可以使用

因为我无法评论你的问题@ReggieB,我认为这是@F4ke 的回答的来源https://gist.github.com/sheeley/7044243

解密部分

def decrypt_cipher_data(key_cipher, cipher_data)
    cipher_data_str = Base64.decode64(cipher_data)
    mcrypt_iv = cipher_data_str[0..15]
    cipher_data_str = cipher_data_str[16..-1]
    cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
    cipher.decrypt
    cipher.padding = 0
    cipher.key = key_cipher
    cipher.iv = mcrypt_iv
    result = cipher.update(cipher_data_str)
    result << cipher.final
end

enc_key = REXML::XPath.first(response.document, "//xenc:EncryptedKey//xenc:CipherData/xenc:CipherValue").text
enc_value = REXML::XPath.first(response.document, "//xenc:EncryptedData/xenc:CipherData/xenc:CipherValue").text
private_key = OpenSSL::PKey::RSA.new(CONFIG_PRIVATE_KEY)
data_key = private_key.private_decrypt(Base64.decode64(enc_key), OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)

actual_output = decrypt_cipher_data(data_key, enc_value) 
clean_output = actual_output.slice(0..(actual_output.index('</Assertion>') + '</Assertion>'.length-1))