I'm doing an SAML AUTHENTIFICATION, and when I received the xml, a part of it is ecrypted. This is the part I need (contains name, email etc.)
For that I have a private key to decrypt it, but I don't have any idea how to do that.
I am here:
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
and so, ret is suposed to be a decrypted xml that I can use, but it always stays at nil (rescue nil, to avoid 500)
I use OneLogin::RubySaml and XMLSecurity
but I have no idea what I've done wrong,
anybody ?
finally, I succeeded to fix the problem :
Here the solution:
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))
so clean_output is the final xml decrypted, ready to use
Because I can't comment on your question #ReggieB, here's where the source of #F4ke's answer I think https://gist.github.com/sheeley/7044243
For the decryption part
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))
Related
I was playing with QLDB of Amazon with ruby and used the aws-sdk-qldb and aws-sdk-qldbsession gem. I was getting result as IonBinary. But not able to decode and parse it.
Following is the code
cred = Aws::Credentials.new(ENV['AWS_ACCESS_KEY'], ENV['AWS_SECRET_ACCESS_KEY'])
qldb_session_client = Aws::QLDBSession::Client.new(region: 'ap-southeast-1', credentials: cred)
start_session_req = Aws::QLDBSession::Types::StartSessionRequest.new
start_session_req.ledger_name = 'ledger-test'
command_request = Aws::QLDBSession::Types::SendCommandRequest.new
command_request.start_session = start_session_req
resp = qldb_session_client.send_command(command_request)
session_token = resp.start_session.session_token
command_request = Aws::QLDBSession::Types::SendCommandRequest.new
command_request.session_token = session_token
command_request.start_transaction = Aws::QLDBSession::Types::StartTransactionRequest.new
resp = qldb_session_client.send_command(command_request)
transaction_id = resp.start_transaction.transaction_id
command_request = Aws::QLDBSession::Types::SendCommandRequest.new
command_request.session_token = session_token
command_request.execute_statement = Aws::QLDBSession::Types::ExecuteStatementRequest.new
command_request.execute_statement.transaction_id = transaction_id
command_request.execute_statement.statement = 'select * from testing'
resp = qldb_session_client.send_command(command_request)
now if I use the following code
resp.execute_statement.first_page.values[0]
I get
{:ion_binary=>"\xE0\x01\x00\xEA\xEE\x9A\x81\x83\xDE\x96\x87\xBE\x93\x89firstname\x88lastname\xDE\x9D\x8A\x8Dtesting first\x8B\x8Ctesting last", :ion_text=>"[FILTERED]"}
I am not able to decode this ion_binary using binary parser.
Decoding the stream is likely to be done with Aws::EventStream::Decoder#decode. That said, somewhat like below should work.
Aws::EventStream::Decoder.new.decode(
StringIO.new(result[:ion_binary])
)
Going blind here.. I can't understand why these 2 strings are not equal.. When I puts them to the terminal they are both class string and when I just compare the output they ARE equal. But somehow in my code they are not.. I can't figure out why.
Here is my Ruby code:
def prep_for_duplicate_webhook
#redis_cart = Redis.new
cart_stamp_saved = #redis_cart.get("cart_stamp_saved")
if cart_stamp_saved.nil?
cart_stamp_saved = {}
cart_stamp_saved[:token] = cart_params['token']
cart_stamp_saved[:updated_at] = cart_params['updated_at']
#redis_cart.set("cart_stamp_saved", cart_stamp_saved.to_json)
end
#cart_stamp_incoming = {}
#cart_stamp_incoming["token"] = cart_params['token']
#cart_stamp_incoming["updated_at"] = cart_params['updated_at']
end
def duplicate_webhook?
prep_for_duplicate_webhook
#cart_stamp_saved = redis_cart.get("cart_stamp_saved")
cart_stamp_saved == cart_stamp_incoming.to_json
end
And then the hash's I'm comparing are these two:
cart_stamp_saved = {"token"=>"4a093432ba5c430dd545b16c0e89f187",
"updated_at"=>"2017-02-17T15:27:22.923Z"}
cart_stamp_incoming= {"token"=>"4a093432ba5c430dd545b16c0e89f187",
"updated_at"=>"2017-02-17T15:27:22.923Z"}
If I just copy and paste the above into a new page, and the do this, the response is true
pp cart_stamp_saved == cart_stamp_incoming.to_json
What am I missing?
I want crypto a string and pass to Rails app,so I find the crypto library both in Nodejs and Ruby.
In Nodejs:
var crypto = require('crypto'),
algorithm = 'aes-256-ctr',
password = 'd6F3Efeqd6F3Efeqd6F3Efeqd6F3Efeq';
function encrypt(text){
var cipher = crypto.createCipher(algorithm,password)
var crypted = cipher.update(text,'ascii',"base64")
crypted += cipher.final("base64");
return crypted;
}
The result is :
encrypt("1") //-输出 2g==
In Ruby
def encrypt(des_text)
des = OpenSSL::Cipher::Cipher.new('aes-256-ctr')
des.encrypt
des.key = 'd6F3Efeqd6F3Efeqd6F3Efeqd6F3Efeq'
result = des.update(des_text)
result << des.final
return Base64.encode64 result
end
The result is :
encrypt("1") # 输出 1A==
So I use the same way and key to crypto a same string,Why the result is not the same?
Difference between crypto.createCipher(algorithm, password) and crypto.createCipheriv(algorithm, key, iv) is that password is used to derive key and IV.
var crypto = require('crypto'),
algorithm = 'aes-256-ctr',
key = 'd6F3Efeqd6F3Efeqd6F3Efeqd6F3Efeq',
iv = "1234567890123456";
function encrypt(text){
var cipher = crypto.createCipheriv(algorithm,key,iv)
var crypted = cipher.update(text,'utf-8',"base64")
crypted += cipher.final("base64");
return crypted;
}
console.log(encrypt("1")); // return bQ==
In Ruby, if you haven't specify iv then it will use a default iv.
require 'openssl'
require 'base64'
def encrypt(des_text)
des = OpenSSL::Cipher::Cipher.new('aes-256-ctr')
des.encrypt
des.key = 'd6F3Efeqd6F3Efeqd6F3Efeqd6F3Efeq'
des.iv = "1234567890123456"
result = des.update(des_text)
result << des.final
return Base64.encode64 result
end
p encrypt("1").strip # return bQ==
I understand what causes the wrong number of arguments error but my code doesn't pass any parameters to initialize any of the classes so I'm not sure at all why my code is giving me this error. I'm also pretty new to Ruby on Rails so that doesn't help things. My code is below:
def create_google_file
#products = Product.find(:all)
file = File.new('dir.xml','w')
doc = REXML::Document.new
root = REXML::Element.new "rss"
root.add_attribute("xmlns:g", "http://base.google.com/ns/1.0")
root.add_attribute("version", "2.0")
channel = REXML::Element.new "channel"
root.add_element channel
title = REXML::Element.new "title"
title.text = "Sample Google Base"
channel.add_element title
link = REXML::Element.new "link"
link.text = "http://base.google.com/base/"
channel.add_element link
description = REXML::Element.new "description"
description.text = "Information about products"
channel.add_element description
#products.each do |y|
item = channel.add_element("item")
id = item.add_element("g:id")
id.text = y.id
title = item.add_element("title")
title.text = y.title
description = item.add_element("description")
description.text = y.description
googlecategory = item.add_element("g:google_product_category")
googlecategory.text = y.googlecategory
producttype = item.add_element("g:product_type")
producttype.text = y.producttype
link = item.add_element("link")
link.text = y.link
imglink = item.add_element("g:image_link")
imglink.text = y.imglink
condition = item.add_element("condition")
condition.text = y.condition
availability = item.add_element("g:availability")
availability.text = y.availability
price = item.add_element("g:price")
price.text = y.price "USD"
gtin = item.add_element("g:gtin")
gtin.text = y.gtin
brand = item.add_element("g:brand")
brand.text = y.brand
mpn = item.add_element("g:mpn")
mpn.text = y.mpn
expirationdate = item.add_element("g:expiration_date")
expirationdate.text = y.salepricedate
end
doc.add_element root
file.puts doc
file.close
end
The error I'm getting is:
ArgumentError in ProductsController#create_google_file
wrong number of arguments (1 for 0)
At the request of the poster, I am putting my comments in to an answer:
Based purely on the consistency of the other lines, but without knowing which line is actually failing, it may be this part: price.text = y.price "USD". Is y.price a method that takes in a parameter? Is it defined as def price(type) or something? If not, if it doesn't take any parameters, then it's because you're not supposed to send any parameters to that method. It looks like it's just a getter.
#FranklinJosephMoormann As I suspected, that's the line. Were you trying to make a string like "4.50 USD"? Then you probably wanted: price.text = "#{y.price} USD". That will take the result of y.price and put it in a string, and allow you to keep typing more in the string. It's called string interpolation.
I'm trying to have a form usable for both creating a new record or updating another. Currently it is doing it through the value of a textbox (new or edit). The structure works fine, but for some reason, when it is performing the edit function, it is saving changes to the wrong record. For instance, if I am editing record 1027, when i submit it, it'll update record 1073. Its consistent, it'll always update the same, wrong record. Edit 1000, it'll update 1073; if i update 1081, it'll update 1073, and so on. Is there a way to specify which record it should be editing? yes, the record number is the primary key/id. Heres the code:
Private Sub btnSubmit_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strTable As String
Dim strField As String
Dim ID As Long
Dim newID As Long
strTable = "record_holdData"
Set db = CurrentDb
Set rs = db.OpenRecordset(strTable)
'button has 2 modes
If txtMode.Value = "NEW" Then
With rs
.AddNew
.Fields("PO_no") = txtPONum
.Fields("prodSupervisor") = cboProdSup
.Fields("qaSupervisor") = cboQASup
.Fields("labTech") = cboLabTech
.Fields("flavor") = cboFlavor
.Fields("lineNumber") = cboLineNumber
.Fields("container") = cboContainer
.Fields("package") = cboPackage
.Fields("holdQty") = txtQty
.Fields("productionDate") = txtProdDate
.Fields("dateCode") = txtDatecode
.Fields("component") = cboComponent
.Fields("nonconformance") = cboDiscrepancy
.Fields("foundDuring") = cboFoundAt
.Fields("responsibility") = cboRespCode
.Fields("comments") = txtDescription
.Fields("rootCause") = txtRootCause
.Fields("holdStatus") = 1
.Fields("dateOpened") = Now()
.Update
.Bookmark = .LastModified
newID = !ID
End With
MsgBox ("Hold information saved!")
btnPrintTag.Enabled = True
DoCmd.OpenReport "Holdtag", acViewPreview, , "[ID] = " & newID
DoCmd.Close
ElseIf txtMode.Value = "EDIT" Then
'do editing stuff
With rs
.Edit
.Fields("PO_no") = txtPONum
.Fields("prodSupervisor") = cboProdSup
.Fields("qaSupervisor") = cboQASup
.Fields("labTech") = cboLabTech
.Fields("flavor") = cboFlavor
.Fields("lineNumber") = cboLineNumber
.Fields("container") = cboContainer
.Fields("package") = cboPackage
.Fields("holdQty") = txtQty
.Fields("productionDate") = txtProdDate
.Fields("dateCode") = txtDatecode
.Fields("component") = cboComponent
.Fields("nonconformance") = cboDiscrepancy
.Fields("foundDuring") = cboFoundAt
.Fields("responsibility") = cboRespCode
.Fields("comments") = txtDescription
.Fields("rootCause") = txtRootCause
.Fields("lastEditDate") = Now()
.Update
End With
MsgBox ("Information Updated")
End If
End Sub
Sorry i caught it. Problem was I was basically redefining the recordset each time the subroutine was called. I changed the second block to the following:
ElseIf txtMode.Value = "EDIT" Then
'do editing stuff
Set rs = db.OpenRecordset("SELECT * FROM record_holdData WHERE ID=" & txtID)
With rs
.Edit
.Fields("PO_no") = txtPONum
.Fields("prodSupervisor") = cboProdSup
.Fields("qaSupervisor") = cboQASup
.Fields("labTech") = cboLabTech
.Fields("flavor") = cboFlavor
.Fields("lineNumber") = cboLineNumber
.Fields("container") = cboContainer
.Fields("package") = cboPackage
.Fields("holdQty") = txtQty
.Fields("productionDate") = txtProdDate
.Fields("dateCode") = txtDatecode
.Fields("component") = cboComponent
.Fields("nonconformance") = cboDiscrepancy
.Fields("foundDuring") = cboFoundAt
.Fields("responsibility") = cboRespCode
.Fields("comments") = txtDescription
.Fields("rootCause") = txtRootCause
.Fields("lastEditDate") = Now()
.Update
End With