3

I am trying to encrypt a small string using Python and Ruby. I've written code in both these languages that should do exactly the same thing:

In Python:

from Crypto.PublicKey import RSA
from Crypto.Util import asn1
from Crypto import Random
import sys, time, signal, socket, requests, re, base64

pubkey = "9B596422997705A8805F25232C252B72C6B68752446A30BF9117783FE094F8559CA4A7AA5DBECAEC163596E96CD9577BDF232EF2F45DC474458BDA8EC272311924B8A176896E690135323D16800CFB9661352737FEDA9FB8DD44B6025EA8037CBA136DAE2DC0061B2C66A6F564E2C9E9579DAFD9BFF09ACF3B6E39BF363370F4A8AD1F88E3AE9A7F2C1B1C75AC00EAE308F57EC9FBDA244FC8B0D1234677A6BEE228FEE00BF653E8E010D0E59A30D0A1194298E052399A62E6FBD490CF03E16A1166F901E996D53DE776169B4EE8705E1512CCB69F8086C66213667A070A65DA28AF18FC8FC01D37158706A0B952D0963A9A4E4A6451758710C9ADD1245AB057389535AB0FA1D363A29ED8AE797D1EE958352E55D4AD4565C826E9EF12FA53AE443418FD704091039E190690FD55BF32E7E8C7D7668B8F0550C5E650C7D021F63A5055B7C1AEE6A669079494C4B964C6EA7D131FA1662CF5F5C83721D6F218038262E9DDFE236015EE331A8556D934F405B4203359EE055EA42BE831614919539A183C1C6AD8002E7E58E0C2BCA8462ADBF3916C62857F8099E57C45D85042E99A56630DF545D10DD338410D294E968A5640F11C7485651B246C5E7CA028A5368A0A74E040B08DF84C8676E568FC12266D54BA716672B05E0AA4EE40C64B358567C18791FD29ABA19EACA4142E2856C6E1988E2028703B3E283FA12C8E492FDB"

foobar = "foobar"

pubkey_int = long(pubkey,16)
pub_exp = 65537L
pubkey_obj = RSA.construct((pubkey_int, pub_exp))
encypted_data =  pubkey_obj.encrypt(foobar, pub_exp)
encypted_data_b64 = base64.b64encode(encypted_data[0])

print encypted_data_b64

In Ruby:

require 'openssl'
require 'base64'

pubkey = "9B596422997705A8805F25232C252B72C6B68752446A30BF9117783FE094F8559CA4A7AA5DBECAEC163596E96CD9577BDF232EF2F45DC474458BDA8EC272311924B8A176896E690135323D16800CFB9661352737FEDA9FB8DD44B6025EA8037CBA136DAE2DC0061B2C66A6F564E2C9E9579DAFD9BFF09ACF3B6E39BF363370F4A8AD1F88E3AE9A7F2C1B1C75AC00EAE308F57EC9FBDA244FC8B0D1234677A6BEE228FEE00BF653E8E010D0E59A30D0A1194298E052399A62E6FBD490CF03E16A1166F901E996D53DE776169B4EE8705E1512CCB69F8086C66213667A070A65DA28AF18FC8FC01D37158706A0B952D0963A9A4E4A6451758710C9ADD1245AB057389535AB0FA1D363A29ED8AE797D1EE958352E55D4AD4565C826E9EF12FA53AE443418FD704091039E190690FD55BF32E7E8C7D7668B8F0550C5E650C7D021F63A5055B7C1AEE6A669079494C4B964C6EA7D131FA1662CF5F5C83721D6F218038262E9DDFE236015EE331A8556D934F405B4203359EE055EA42BE831614919539A183C1C6AD8002E7E58E0C2BCA8462ADBF3916C62857F8099E57C45D85042E99A56630DF545D10DD338410D294E968A5640F11C7485651B246C5E7CA028A5368A0A74E040B08DF84C8676E568FC12266D54BA716672B05E0AA4EE40C64B358567C18791FD29ABA19EACA4142E2856C6E1988E2028703B3E283FA12C8E492FDB"

foobar = "foobar"

asn1_sequence = OpenSSL::ASN1::Sequence.new(
  [
    OpenSSL::ASN1::Integer.new("0x#{pubkey}".to_i(16)),
    OpenSSL::ASN1::Integer.new("0x10001".to_i(16))
  ]
)

public_key = OpenSSL::PKey::RSA.new(asn1_sequence)
data = Base64.encode64(public_key.public_encrypt(foobar))
puts data

Both these scripts are trying to encrypt the string foobar using the same public key. I expected both of them to output the same results each time, however this is not the case. Furthermore, every time the Ruby Script is executed, it outputs a different result.

Can someone help me identify the difference between these two scripts that is responsible for this behavior?

1 Answer 1

1

I am able to solve this issue by reading the documentation for Class _RSAobj (https://www.dlitz.net/software/pycrypto/api/current/Crypto.PublicKey.RSA._RSAobj-class.html#encrypt)

Attention: this function performs the plain, primitive RSA encryption (textbook). In real applications, you always need to use proper cryptographic padding, and you should not directly encrypt data with this method. Failure to do so may lead to security vulnerabilities. It is recommended to use modules Crypto.Cipher.PKCS1_OAEP or Crypto.Cipher.PKCS1_v1_5 instead.

Looks like cryptographic padding is not used by default in the RSA module for Python, hence the difference.

Modified Python Script:

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import sys, time, signal, socket, requests, re, base64

pubkey = "9B596422997705A8805F25232C252B72C6B68752446A30BF9117783FE094F8559CA4A7AA5DBECAEC163596E96CD9577BDF232EF2F45DC474458BDA8EC272311924B8A176896E690135323D16800CFB9661352737FEDA9FB8DD44B6025EA8037CBA136DAE2DC0061B2C66A6F564E2C9E9579DAFD9BFF09ACF3B6E39BF363370F4A8AD1F88E3AE9A7F2C1B1C75AC00EAE308F57EC9FBDA244FC8B0D1234677A6BEE228FEE00BF653E8E010D0E59A30D0A1194298E052399A62E6FBD490CF03E16A1166F901E996D53DE776169B4EE8705E1512CCB69F8086C66213667A070A65DA28AF18FC8FC01D37158706A0B952D0963A9A4E4A6451758710C9ADD1245AB057389535AB0FA1D363A29ED8AE797D1EE958352E55D4AD4565C826E9EF12FA53AE443418FD704091039E190690FD55BF32E7E8C7D7668B8F0550C5E650C7D021F63A5055B7C1AEE6A669079494C4B964C6EA7D131FA1662CF5F5C83721D6F218038262E9DDFE236015EE331A8556D934F405B4203359EE055EA42BE831614919539A183C1C6AD8002E7E58E0C2BCA8462ADBF3916C62857F8099E57C45D85042E99A56630DF545D10DD338410D294E968A5640F11C7485651B246C5E7CA028A5368A0A74E040B08DF84C8676E568FC12266D54BA716672B05E0AA4EE40C64B358567C18791FD29ABA19EACA4142E2856C6E1988E2028703B3E283FA12C8E492FDB"

foobar = "foobar"

pubkey_int = long(pubkey,16)
pub_exp = 65537L
pubkey_obj = RSA.construct((pubkey_int, pub_exp))
cipher = PKCS1_v1_5.new(pubkey_obj)
encypted_data = cipher.encrypt(foobar)
encypted_data_b64 = base64.b64encode(encypted_data)

print encypted_data_b64
Sign up to request clarification or add additional context in comments.

2 Comments

just a quick question, so now you have both script that generates the same result and this result is different each time you run the script ?
@Darkos its different each time for both Scripts, which is the expected results. I will post the modified python script.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.