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,但它总是停留在nil
(rescue nil
,以避免500)
我用OneLogin::RubySaml
和XMLSecurity
但我不知道自己做错了什么,
有人吗?
终于,我成功解决了这个问题:
解决方法在这里:
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))
我正在进行 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,但它总是停留在nil
(rescue nil
,以避免500)
我用OneLogin::RubySaml
和XMLSecurity
但我不知道自己做错了什么,
有人吗?
终于,我成功解决了这个问题: 解决方法在这里:
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))