I want to implement the following function using python, it uses public key to encrypt the password and then using base64 to encode it. I have searched many answers but I didn’t find a solution, I think probably I didn’t understand them. Would you please give me some advice?
// # java code public static String encryptRSA(String password, String publicKey) { try { byte[] decoded = Base64.decode(publicKey); RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA") .generatePublic(new X509EncodedKeySpec(decoded)); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); String outStr = Base64.encode(cipher.doFinal(password.getBytes("UTF-8"))); return outStr; } catch (Exception e) { } return null; }
I use the following code, but it raises error M2Crypto.RSA.RSAError
.
# python code import base64 import M2Crypto pub = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQClnY+3rAf/az9t2bxC80TObpZ2ZCH1xSjPt9QtXl6k6UtD7mQcI2CWSwnDgKJr2m2WnM1kR6X+oOL61lXO0gSuuD8tWOx/knZA2VaSTLdsHBDLOX3e6Fo/O3CtoLVwO5FYFBIFHXMoikPkR8tFIOLWsX0y3slLQQShwSJAHytP4QIDAQAB" password = 123 def public_encrypt(public_key, password): rsa_pub = M2Crypto.RSA.load_key_string(public_key.encode('utf-8')) ctxt_pub = rsa_pub.public_encrypt(password.encode(), M2Crypto.RSA.pkcs1_padding) ctxt64_pub = base64.b64encode(ctxt_pub).decode() return ctxt64_pub res = public_encrypt(pub, password) print('res:', res)
Advertisement
Answer
The full error message is: M2Crypto.RSA.RSAError: no start line, indicating that the key is imported incorrectly.
load_key_string()
requires a PEM-encoded private key in PKCS#1 or PKCS#8 format, but no public key. A PEM encoded public key in X.509/SPKI format can be imported with load_pub_key_bio()
.
From the posted X.509/SPKI key a PEM encoded key can be created by adding a newline after every 64 characters and adding a corresponding header and footer:
import M2Crypto x509 = '''-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQClnY+3rAf/az9t2bxC80TObpZ2 ZCH1xSjPt9QtXl6k6UtD7mQcI2CWSwnDgKJr2m2WnM1kR6X+oOL61lXO0gSuuD8t WOx/knZA2VaSTLdsHBDLOX3e6Fo/O3CtoLVwO5FYFBIFHXMoikPkR8tFIOLWsX0y 3slLQQShwSJAHytP4QIDAQAB -----END PUBLIC KEY-----''' bio = M2Crypto.BIO.MemoryBuffer(x509) rsa_pub = M2Crypto.RSA.load_pub_key_bio(bio)
Another issue is that there is no encode()
defined for an integer, but presumably password
is supposed to be a string and this is just a copy/paste error.
With these changes the code works.
Note that a 1024 bits RSA key (like yours) is insecure nowadays, instead the length should be >= 2048 bits.