Reputation: 363
My goal is to integrate an API service which wants me to generate a signature by following these steps.
Step 3 is the signature generation step. In my ruby application this is how I have implemented the steps.
def dynamic_signature
raw_data = "#{client_id}.#{Time.now.to_i}"
filepath = "public_key.pem"
public_key = OpenSSL::PKey::RSA.new File.read(filepath)
Base64.strict_encode64(public_key.public_encrypt(raw_data)).encode("UTF-8")
end
But the API service rejects this signature. They have code snippet examples in php so tried this process in php with the following code. I have used the variables from the ruby code above for representation.
<?php
$plainData = <raw_data>;
$publicKey = <public_key.to_s>;
openssl_public_encrypt($plainData, $encrypted, $publicKey, OPENSSL_PKCS1_OAEP_PADDING);
echo base64_encode($encrypted);
?>
This signature gets accepted by the API service.
I did some manual inspection and both base64 outputs were obviously different. In ruby I have tried with and without enforcing an encode("UTF-8")
.
Interestingly the following statement returns true, no matter if I do a strict_encode64
or encode64
or append encode("UTF-8")
at the end.
base64_generated_in_ruby.bytes == base64_generated_in_php.bytes
I did this equality check by copy pasting the base64 encoded strings in the ruby console.
I suspect base64 encoding is working differently for escape characters in both these languages. Any help is appreciated.
Edit 1: Adding an example.
"g\xF3\f%\xA2\xC0(\xCBYAw\x80\xA5 c\x9DR\xC7r\xFE\xAF \xADJ\xCBy\x8D\xC8kd#\xD3\x04L(\x9B\xC0V\n\xCD\xFF\xD4\rj\xF0\x12\x86\xEC5\xC6ev\xCEUD\x9B\xA2\xAD\x9F{\xC8\xF5\x8A\x00->\xB5\xA4f\x05\x9F\xE1\x81u\xB5\x87\xD4\xD7\xA7\xCC\xE0:\xC9\xF3,\x8D(\x10\xEC\\\xE8'\r\xFA\x14\x82\x8A\xCF_^\xAA\x94\x17\x15\xD0Qw\x18\xDB\xE7\t\xEEy\x9E04\x94\xDE\xFB\xF6\xEB:\xDF\x90\xDER\xEB\xF1c\xF2\x98\x00\x9CM\x16\xA6{\x12\xA8\xA2\xE7\x00\x89\xDE\xB4\x9C\xB1\xE9\x81\x9D\xB4\xC8~q\x8A\xBDu#\xD2\xD2\x19T\xE4H\x7F\x0E\xDF\xECV\x8E\rF\xF7\x12m\x1C\xFE-\xC2gO\x90\xEDp\x88\x1A\x1D\t4\xC2\r!\xD5Y\xC3\xBB\xB8*B%\x00\xDF\xE2s\x8A\x19j\xFB\xEBy\xD7\xD6\xF5\x06\x99\xEE\xEA\xE4\xA3\x83\x97\xDB\x95\xA2o\x86\x97c\xA8w\xAAb\xEF\x00e\xC4\b\xD3\xEB\xFB\x86\xF4\xE2!\xF1{\xA5\x80\xD7\xC4\xC4\x01,\xBFj-"
Base64.strict_encode64(rsa_string)
"Z/MMJaLAKMtZQXeApSBjnVLHcv6vIK1Ky3mNyGtkI9METCibwFYKzf/UDWrwEobsNcZlds5VRJuirZ97yPWKAC0+taRmBZ/hgXW1h9TXp8zgOsnzLI0oEOxc6CcN+hSCis9fXqqUFxXQUXcY2+cJ7nmeMDSU3vv26zrfkN5S6/Fj8pgAnE0WpnsSqKLnAInetJyx6YGdtMh+cYq9dSPS0hlU5Eh/Dt/sVo4NRvcSbRz+LcJnT5DtcIgaHQk0wg0h1VnDu7gqQiUA3+Jzihlq++t519b1Bpnu6uSjg5fblaJvhpdjqHeqYu8AZcQI0+v7hvTiIfF7pYDXxMQBLL9qLQ=="
base64_encode($rsa_string)
"Z/MMJaLAKMtZQXeApSBjnVLHcv6vIK1Ky3mNyGtkI9METCibwFYKzf/UDWrwEobsNcZlds5VRJuirZ97yPWKAC0+taRmBZ/hgXW1h9TXp8zgOsnzLI0oEOxc6CcN+hSCis9fXqqUFxXQUXcY2+cJ7nmeMDSU3vv26zrfkN5S6/Fj8pgAnE0WpnsSqKLnAInetJyx6YGdtMh+cYq9dSPS0hlU5Eh/Dt/sVo4NRvcSbRz+LcJnT5DtcIgaHQk0wg0h1VnDu7gqQiUA3+Jzihlq++t519b1Bpnu6uSjg5fblaJvhpdjqHeqYu8AZcRcYtPr+4b04iHxe6WA18TEASy/ai0="
Upvotes: 0
Views: 458
Reputation: 363
The ruby public_encrypt
method does not include a padding argument by default. Use public_encrypt(raw_data, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
to add the relevant padding argument. In the supplied php code submitted padding is explicitly mentioned.
Upvotes: 0