I have been trying to convert the below java code to its python equivalent:
Encrypt.java
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import org.apache.commons.codec.binary.Base64;
//import org.jose4j.base64url.Base64;
public class Encrypt {
public static void main(String[] args)
throws InvalidKeySpecException, NoSuchAlgorithmException, UnsupportedEncodingException, CertificateException, FileNotFoundException {
PublicKey pubKey;
Object localObject1 = new
String("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA76y3+1w4Ld9Q4WvHQkCkg6qjwq2wWOYMV9nAthX6ugatNlShRb2gBmy"
+
"qvh7tOYHhjAhkG9Z33jCVinPuhgb0ioa5/sFAgP5LDdo5SBk4b4n/wRUbdMhfFFcTT0As2OsmdBc2iONUaG4g3WjgRODxy6LLahms6YgTnG+AqeDo8LpXxsiFXe"
+
"iqGUyKQU1l16BPc2xyG+tDitFbKHx9pDL12e/w5b4G4Zg4yJgbNlZrGc3Udz5EbDREnAwirjAA3F6x2DF3j746vETb1g2y6+P5sS4lvG3XmaB1JBlhNh5qpqADRqmE"
+ "MWeiYhrRcK9KjS1URSUizGPo96d8R82DmXvYKQIDAQAB");
//localObject1 = new X509EncodedKeySpec(Base64.decode(((String)localObject1).getBytes("utf-8")));
localObject1 = new X509EncodedKeySpec(Base64.decodeBase64(((String)localObject1).getBytes("utf-8")));
localObject1 = KeyFactory.getInstance("RSA").generatePublic((KeySpec)localObject1);
System.out.println((PublicKey)localObject1);
System.out.println("___________________________________________________________________________________________________________________________________________________");
// String secret_pub_key= //"-----BEGIN RSA PUBLIC KEY-----" +
// "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwkvq7mHuTMGeJF/qiAot"+
// "OcLTd6hjDEcMHIk2IY35JInuypD6WieogOxSS6kHYho/U+BW/Cgz0XjziPIQSJZx"+
// "AGOrtdZrTa6n6S6I65YB2wPB93lLi/qnBmUSetEgAgM+MOfiYT8Dift9Mut+BvbE"+
// "iFMH163ovoiTyLDpbTYDB6InzFzu1l7G01pi/ZAc69kWrJ+yNMEUcnAerRPt30et"+
// "XAbKD2lC696VJa/2xtWZ5T7vwMpFLIaGFAg228ZifgwDIRFsBmwPsAsngQSGVVBo"+
// "Ijm3fb0PUDV4MTw+cNT0ldHbYCAWy6zgA0K7eL5LcUN8+ai7u6VMWYUT4FAvYNiP"+
// "IwIDAQAB";
// //"-----END RSA PUBLIC KEY-----";
// X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(Base64.decode(secret_pub_key));
// KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
Object secret_pub_key= new String(//"-----BEGIN RSA PUBLIC KEY-----" +
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApzQvzc+chU92SSh2eukY"+
"ycdTJArCjL4+AqW8a2lKZ2jb5g04q6FGSRJgNkuggXt7U5ys5pb+J0699vY9rzgz"+
"+WmH6W/ZRZ2hAf3rtWaC1YYetD1SfmD2OGItGfkFYuppjjjKXEnTDzCBQT5IL7hd"+
"lnlCfpDkcPmJWvKJU+5gJek9RanVQYXLWgtOIVrQ7LJhQEFDMuYSw+rz7+paBxNq"+
"XeHTvDk/ylGtHjb3xOvbVg3DfL2z76YYX69Ae3Cd1rlqaY0IT01k3oeqNZg3638T"+
"i8l+6ytwChRhtOHZh5XCaW6Cfbz2nezgYgY1qTAKK05o8Of+W/dErUt4166qnjBl"+
"+wIDAQAB");
//"-----END RSA PUBLIC KEY-----";
secret_pub_key = new X509EncodedKeySpec(Base64.decodeBase64(((String)secret_pub_key).getBytes("utf-8")));
secret_pub_key = KeyFactory.getInstance("RSA").generatePublic((KeySpec)secret_pub_key);
pubKey = (PublicKey)secret_pub_key;
Object localObject;
Lc lc = new Lc();
System.out.println("\n\nlc.pub is" + lc.pub);
System.out.println("\n\n\nokokokokok" + pubKey.getEncoded());
//byte[] arrayOfByte = new String(Base64.encodeBase64(lc.pub.getEncoded())).getBytes();
byte[] arrayOfByte = new String(Base64.encodeBase64(pubKey.getEncoded())).getBytes();
StringBuilder localStringBuilder1 = new StringBuilder();
int i = 0;
while (i < arrayOfByte.length) {
if (arrayOfByte.length > i + 200) {
localObject = Arrays.copyOfRange(arrayOfByte, i, i + 200);
} else {
localObject = Arrays.copyOfRange(arrayOfByte, i, arrayOfByte.length + 1);
}
StringBuilder localStringBuilder2 = new StringBuilder();
lc.pub = (PublicKey)localObject1;
localObject = new String((byte[])localObject);
localStringBuilder1.append(lc.upperDot((String)localObject) + ":::");
i += 200;
}
System.out.println("The ducking key is " + localStringBuilder1.toString());
}
}
Lc.java
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class Lc {
public static PublicKey pub;
public static PrivateKey pri;
public byte[] by;
public String dot;
public Lc() {
Object localObject = "RSA";
try
{
localObject = KeyPairGenerator.getInstance((String)localObject);
KeyPair localKeyPair = ((KeyPairGenerator)localObject).generateKeyPair();
localObject = localKeyPair.getPublic();
pub = (PublicKey)localObject;
localObject = localKeyPair.getPrivate();
pri = (PrivateKey)localObject;
}
catch (NoSuchAlgorithmException localNoSuchAlgorithmException)
{
localNoSuchAlgorithmException.printStackTrace();
}
}
public static String upperDot(String paramString)
{
Object localObject = "RSA/ECB/PKCS1Padding";
try
{
Cipher localCipher = Cipher.getInstance((String)localObject);
localObject = pub;
int i = 1;
localCipher.init(i, (Key)localObject);
localObject = paramString.getBytes();
byte[] arrayOfByte1 = localCipher.doFinal((byte[])localObject);
byte[] arrayOfByte2 = Base64.encodeBase64(arrayOfByte1);
localObject = new String(arrayOfByte2);
return (String)localObject;
}
catch (Exception localException)
{
System.out.print(localException);
}
return null;
}
}
please ignore the bad design of the above 2 java files and the debug print statements
The output that the above produces, which is of interest to me is the content of the last output statement :
The ducking key is t4z2jf9GKtKvXiXCPYU3u7Y0LwQOOeQBVi+YRATc3GqyTNb085bRLUVqiNT5v/ZcZl2FZPegeN8OTG9vPbwuY1HrQ04xv0vUf3ohJORiUXwEQtoBVMDnKHib50FPZCbAZIp/1u0KgEPBV9rEe7BmHi2UGCNnp0e50G68cBPLknUinBIIYIIrw/o3U4SAT+uBdo6wyi/x0tWR3El8gJpL34JJVWzdzi4y61cPZI31gxyY19t1EzzmtqB0wnjV5RvTsavR5s3RgtBu3EV+b43poam2K0CsRyfB2lFawkZBnvRL6GzvozBpUYe4awdPbU4Pjvuju5B3zWXloQ5kMVZAkg==:::MpcHcJWhGdYrS1VLza+ereOU1ZRZ9LyVTN0KBBdQLIjYXChX1eKtRdftrF306L5BE8Ni9ibTylbcsc6tocphVpYnCvYN2eKVcEoHLyk9Iz/Cf2ikYJCUFtHh/cPnSILhwI7txdVds0Il58uDMevMnvvRntqVR7nw6UUmUVwmtFvNWVdceP61BHc9YsDMdQs8jPOeGAHWmqA2g4ODYB2W07yQhmwNIQZEmkmrfRHUd1dqM57sIWS9HdgEbrnqhyt1pIWrCxzgYbzZCuaDS/llcFsqgLBbaPpTg2qNUFi2x3r1jJ1UeJeX+y/mOhrEvBXSLmadsCYmEROIutNgoVWigg==:::
Now I want to achieve the exact same behavior through python (2.7 if that matters). I have so far relied on pycrypto and M2Crypto but neither has been helpful.
Here's my attempt at making a python equivalent of the above :
from Crypto.PublicKey import RSA
from base64 import b64decode
from base64 import b64encode
def ecnryptorFun(key, secret):
encrypted = key.encrypt(secret, 1)
final_text = b64encode(encrypted[0])
return final_text
def sayHello(body):
url = 'https://consumer-app-development.appspot.com/api/sayHello'
res = requests.post(url=url, data=body)
return res.text
key64 = b'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA76y3+1w4Ld9Q4WvHQkCkg6qjwq2wWOYMV9nAthX6ugatNlShRb2gBmyqvh7tOYHhjAhkG9Z33jCVinPuhgb0ioa5/sFAgP5LDdo5SBk4b4n/wRUbdMhfFFcTT0As2OsmdBc2iONUaG4g3WjgRODxy6LLahms6YgTnG+AqeDo8LpXxsiFXeiqGUyKQU1l16BPc2xyG+tDitFbKHx9pDL12e/w5b4G4Zg4yJgbNlZrGc3Udz5EbDREnAwirjAA3F6x2DF3j746vETb1g2y6+P5sS4lvG3XmaB1JBlhNh5qpqADRqmEMWeiYhrRcK9KjS1URSUizGPo96d8R82DmXvYKQIDAQAB'
keyDER = b64decode(key64)
keyPub = RSA.importKey(keyDER)
secret = b"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApzQvzc+chU92SSh2eukYycdTJArCjL4+AqW8a2lKZ2jb5g04q6FGSRJgNkuggXt7U5ys5pb+J0699vY9rzgz+WmH6W/ZRZ2hAf3rtWaC1YYetD1SfmD2OGItGfkFYuppjjjKXEnTDzCBQT5IL7hdlnlCfpDkcPmJWvKJU+5gJek9RanVQYXLWgtOIVrQ7LJhQEFDMuYSw+rz7+paBxNqXeHTvDk/ylGtHjb3xOvbVg3DfL2z76YYX69Ae3Cd1rlqaY0IT01k3oeqNZg3638Ti8l+6ytwChRhtOHZh5XCaW6Cfbz2nezgYgY1qTAKK05o8Of+W/dErUt4166qnjBl+wIDAQAB"
#secret1 = b64encode(secret)
arrayOfByte = bytearray(secret)
i = 0
localStringBuilder1 = ""
while i < len(arrayOfByte):
if len(arrayOfByte) > (i+200):
localObject = arrayOfByte[i:i+200]
else:
localObject = arrayOfByte[i:len(arrayOfByte)+1]
localObj_byte_array = bytearray(localObject)
localStringBuilder1 = localStringBuilder1 + ecnryptorFun(keyPub, str(localObject)) + ':::'
#localStringBuilder1 = localStringBuilder1 + ecnryptorFun(encryption_key, localObj_byte_array) + ':::'
i += 200;
print localStringBuilder1
Output of the above python code
vkqbraD/5HMvs9LG59VXCGCLUoJ0msU6fVvLMDCc8fQ41S3R3IC0EfxLCk9FoHUIGK5h90Rd0at2ROvcOVCtESAYZlYYCB1U99NqWCFLvyDBxS4uEAVHD5yv4U82Dmn/p/asi+D/GxnvP/xvyiI+tp39lWx77DuV4hlnRbltHu9f4o4cvqZ+Nn7wCzY1TBzIClT8f4lx2g9E/5+mhfkQIHejGIAMyJXl3xy+qhQSoy8DvudGQU95eGfDRdci4yqOwDeG2+QlUip627tMbttAroWQjM8jC419kFPetTlmV/RczE/vcwnyM3iEnrhB9KnjRLYEecJ8mEYU7L/TxBe+Tg==:::V1oZBPETF9ryap59T4zOwfW0/pASSCULWL8ZlvUrSlRLeaZmIxplNmewqyUnrhwIbnpDvwhmz7+2/Dd2EN4hJndRnGl7aoEX8/GJP0Kz9vL2qEDbIGQC/Dv6O75KPFZ/E06DYLcycLhNZYxudwVP9rJAhFEEMgefpY40v1+B6sqqogrGnZhfwITaqpU0FKTbHSlHUymlD6Cn4lb0yLMISG6MZRQrP5B67UkGexlpxPQTHsXcLy0vTEzMZkvdxbv4YtawNvmgeQEgD1jqIB45pOngrwp3jcs9D9Ib2hCwpOoqkwOV/YaA+XO+dkPo8BxOw5DH/jWRcksb3N65YEmlvQ==:::
Now although the above produces a very similar output but it is not the right one. Why? Because when the output of the java code above is sent to the backend, I receive a HTTP 200 OK and the expected response.
However, when the output of the python code above is sent similarly to the backend, I receive a 500 internal server error, meaning (as per my assumption, given that all the other params, headers etc. remain exactly the same between the java and the python HTTP requests) the input to the backend was not correct and hence it broke (again please ignore the 500, I agree it should be something more meaningful and definitely not a 500)
I do not have access to the backend. It is more of a red team - blue team exercise we are doing
Also, I could possibly invoke the java code above from python and still manage to achieve the end result and get the work done, but that'd be more of a hack, which would although be sufficient, but I am more interested in knowing how exactly can I achieve the same with Python alone.
As per some suggestions in the comments below I tried this as well: So I tried this as well:
from Crypto.Cipher import PKCS1_v1_5
def encryptMsg(secret):
message = secret
key = RSA.importKey(open('myPubkey.pem').read())
cipher = PKCS1_v1_5.new(key)
ciphertext = b64encode(cipher.encrypt(message))
return ciphertext
and then in the while loop, this:
localStringBuilder1 = localStringBuilder1 + encryptMsg(str(localObject)) + ':::'
Still doesn't seem to work. Same results as before.
Thanks to https://stackoverflow.com/users/1816580/artjom-b for pointing me in the right direction in the comments above. Ok. What works is this :
from Crypto.PublicKey import RSA
from base64 import b64decode
from base64 import b64encode
from Crypto.Cipher import PKCS1_v1_5
def encryptMsg(key, secret):
message = secret
cipher = PKCS1_v1_5.new(key)
ciphertext = b64encode(cipher.encrypt(message))
return ciphertext
from Crypto.PublicKey import RSA
from base64 import b64decode
from base64 import b64encode
from Crypto.Cipher import PKCS1_v1_5
import requests
# def ecnryptorFun(key, secret):
# encrypted = key.encrypt(secret, 1)
# final_text = b64encode(encrypted[0])
# return final_text
def encryptMsg(key, secret):
message = secret
cipher = PKCS1_v1_5.new(key)
ciphertext = b64encode(cipher.encrypt(message))
return ciphertext
def sayHello(body):
url = 'https://consumer-app-development.appspot.com/api/sayHello'
res = requests.post(url=url, data=body)
return res.text
# this is basically the keyString value itself
key64 = b'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA76y3+1w4Ld9Q4WvHQkCkg6qjwq2wWOYMV9nAthX6ugatNlShRb2gBmyqvh7tOYHhjAhkG9Z33jCVinPuhgb0ioa5/sFAgP5LDdo5SBk4b4n/wRUbdMhfFFcTT0As2OsmdBc2iONUaG4g3WjgRODxy6LLahms6YgTnG+AqeDo8LpXxsiFXeiqGUyKQU1l16BPc2xyG+tDitFbKHx9pDL12e/w5b4G4Zg4yJgbNlZrGc3Udz5EbDREnAwirjAA3F6x2DF3j746vETb1g2y6+P5sS4lvG3XmaB1JBlhNh5qpqADRqmEMWeiYhrRcK9KjS1URSUizGPo96d8R82DmXvYKQIDAQAB'
keyDER = b64decode(key64)
keyPub = RSA.importKey(keyDER)
secret = b"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApzQvzc+chU92SSh2eukYycdTJArCjL4+AqW8a2lKZ2jb5g04q6FGSRJgNkuggXt7U5ys5pb+J0699vY9rzgz+WmH6W/ZRZ2hAf3rtWaC1YYetD1SfmD2OGItGfkFYuppjjjKXEnTDzCBQT5IL7hdlnlCfpDkcPmJWvKJU+5gJek9RanVQYXLWgtOIVrQ7LJhQEFDMuYSw+rz7+paBxNqXeHTvDk/ylGtHjb3xOvbVg3DfL2z76YYX69Ae3Cd1rlqaY0IT01k3oeqNZg3638Ti8l+6ytwChRhtOHZh5XCaW6Cfbz2nezgYgY1qTAKK05o8Of+W/dErUt4166qnjBl+wIDAQAB"
arrayOfByte = bytearray(secret)
i = 0
localStringBuilder1 = ""
while i < len(arrayOfByte):
if len(arrayOfByte) > (i+200):
localObject = arrayOfByte[i:i+200]
else:
localObject = arrayOfByte[i:len(arrayOfByte)+1]
localObj_byte_array = bytearray(localObject)
localStringBuilder1 = localStringBuilder1 + encryptMsg(keyPub, str(localObject)) + ':::'
i += 200;
print localStringBuilder1
And now the for the string I get the backend responds with 200 OK