Reputation: 4319
I am working on a web application and I need to talk to server in encrypted way using RSA public/private key. I have a public key in a text file like this:
¨Ì�sr�java.math.BigIntegerå¸ü©;˚�I�bitCountIbitLengthI�firstNonzeroByteNumI�lowestSetBitI�signum[
� magnitudet�[Bxr�java.lang.Numberܨïî‡ã��xpˇˇˇˇˇˇˇˇˇˇˇ˛ˇˇˇ˛���ur�[B¨Û¯T‡��xp���ØÕ..˛¶⁄
[í'‰∑S~ÆhU‚Ãu|ˆ*Ÿ"E˝x©àÚ†qçÎU¬òü`Oˇ?{q^⁄/O'•à%œÍ¬S� ∏íU$0≥i‹Hï™è>æ∑÷é˜ FVÚµ™ŒR=*ÑπGF%À¨ËߥÀüm‡(T¨‘Pq.ã3ˇ∑Ò;ªmÔ˙
C–„¿ç5åÌŒææ°4ån”®Å–MAQ’kÜì∑ÊË°ÂÅíîc»AÈ�
∫ıƒËv:eÚDÑØKv3Áq”cO´HÁzπ…ÅÔ©ˇwlWènö◊aAß° m͇ïöH˚Æ)˛WeŸci·JbÜ q˙H£xsq�~��ˇˇˇˇˇˇˇˇˇˇˇ˛ˇˇˇ˛���uq�~����≠íi5˛¸¥Q‚í(2ûfiΩL0ΩÅ≤ò`
÷…7¯ú)K´ºÎW2j·°Ø«¨X”gºŸ«lÇ8øÃ√3RÕ·ƒŸÚ¢fl∆,flr’X∆È|˚ì[Nfl%≈Búp·≤∑◊gπrõà–À≠˛`»Á†U„«¨ë+e|üæÄ®iLˇ⁄q¨@ä;…gRî>òvû+…U^ËÕdT∫|≠˙N"#zßø⁄+Å2ï¢=Nûe≠D˙§∞7X≥QPZ(Û`Ã-àÙ√ÿ÷Û˘£5[ŒÂ◊�IÄfiV bf´ÄÍÚ∫ê!*Ô´õD »E˛˙úhiô{ì“åCZWœ-åWÊ6‘t·x
When I try to base64 encode it the result is:
rO0ABXNyABRqYXZhLm1hdGguQmlnSW50ZWdlcoz8nx+pO/sdAwAGSQAIYml0Q291bnRJAAliaXRMZW5ndGhJABNmaXJzdE5vbnplcm9CeXRlTnVtSQAMbG93ZXN0U2V0Qml0SQAGc2lnbnVtWwAJbWFnbml0dWRldAACW0J4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHD///////////////7////+AAAAAXVyAAJbQqzzF/gGCFTgAgAAeHAAAAEAr80ULi7+ptoVW5In5LdTfq5oVeLMdXwO9irZIkX9eKmI8qBxjetVwpifYE8M/z8ee3Fe2i9PJ6WIJQ/PHOrCUwAJA7iSVQEYAyQwF7Np3BRIlaqPPr631o73IEZW8rWqzlI9KoS5R0Yly6zop7TLn23gKFSs1FBxGi6LCjMe/7fxO7tt7/p/AUPQ48CNNYzGCu3Ovr6hNIxuBBzTqIHQTUFR1WuGk7fm6KHlgZIelAsWY8hB6QC6B3/1xALodjpl8kSErwRLdjPncdNjT6sZSOd6ucmBGu+p/3dsV49umtdhQacCocpt6uCVmkgM+64p/ldl2WMSaeFKYoYgcfpIo3hzcQB+AAD///////////////7////+AAAAAXVxAH4ABAAAAQCtDpJpDDX+Bfy0UeIXkigNMp7evQ5MML2Bsphg1sk3+JwpS6u86wdXMmrhoa/HrFjTZ7zZx2yCOL8WzMMzUh3NGuHE2fKi3xrGLN9y1VjGHul8+5NbTt8lxUKccOGytwbXZ7lym4jQEsut/h5gyOcRoFXjHceskStlfJ++gKhpTP/acaxAijvJZ1IRlD6Ydp4ryQNVXujNZFS6fK36TiJ/I3qnvxfaK4EylaISPU6eZa1E+qSwN1gQs1FQWigQ82DMLYj0w9jW8/mjNRpbEs7l1wBJgN5WCWJmqweA6vK6kCEq76ubRAnIRf76nGhpmXuT0oxDEVpXzy2MV+Y21HTheA==
which always gives me an invalid public key. When I try:
openssl_public_encrypt($data, $encrypted_data, base64_encode($key), OPENSSL_PKCS1_PADDING);
I know that the public key must start with:
-----BEGIN PUBLIC KEY-----
and ending with:
-----END PUBLIC KEY-----
I tried to use:
"-----BEGIN PUBLIC KEY-----\r\n" . chunk_split(base64_encode($key)) . "\r\n-----END PUBLIC KEY-----";
but it is still not working. Can anyone offer any help?
Upvotes: 3
Views: 4053
Reputation: 716
Thank you for the response in Java, it seems to have helped.
However, for the sake of completeness and to help anyone else who may come across this question looking for a PHP solution, I would like to share my solution in PHP.
This is not meant to diminish the helpfulness of the Java answer.
function encrypt($password, $publicKeyBase64String) {
$publicKeyString = "-----BEGIN PUBLIC KEY-----\n" . $publicKeyBase64String . "\n-----END PUBLIC KEY-----";
$publicKey = openssl_pkey_get_public($publicKeyString);
openssl_public_encrypt($password, $encryptedPassword, $publicKey, OPENSSL_PKCS1_PADDING);
return base64_encode($encryptedPassword);
}
Upvotes: 0
Reputation: 93948
You'll need Java code to convert these serialized BigInteger
values to a private key and public key. The base64 encoded binary seems to contain two serialized BigInteger objects, the modulus and the private exponent (which is now exposed). To retrieve PEM encoding it's best to rely on Bouncy Castle to do the conversion:
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import org.bouncycastle.openssl.PEMWriter;
import org.bouncycastle.util.encoders.Base64;
public class KeysFromSerializedBigIntegers {
private static final String FROM_QUESTION = "rO0ABXNyABRqYXZhLm1hdGguQmlnSW50ZWdlcoz8nx+pO/sdAwAGSQAIYml0Q291bnRJAAliaXRMZW5ndGhJABNmaXJzdE5vbnplcm9CeXRlTnVtSQAMbG93ZXN0U2V0Qml0SQAGc2lnbnVtWwAJbWFnbml0dWRldAACW0J4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHD///////////////7////+AAAAAXVyAAJbQqzzF/gGCFTgAgAAeHAAAAEAr80ULi7+ptoVW5In5LdTfq5oVeLMdXwO9irZIkX9eKmI8qBxjetVwpifYE8M/z8ee3Fe2i9PJ6WIJQ/PHOrCUwAJA7iSVQEYAyQwF7Np3BRIlaqPPr631o73IEZW8rWqzlI9KoS5R0Yly6zop7TLn23gKFSs1FBxGi6LCjMe/7fxO7tt7/p/AUPQ48CNNYzGCu3Ovr6hNIxuBBzTqIHQTUFR1WuGk7fm6KHlgZIelAsWY8hB6QC6B3/1xALodjpl8kSErwRLdjPncdNjT6sZSOd6ucmBGu+p/3dsV49umtdhQacCocpt6uCVmkgM+64p/ldl2WMSaeFKYoYgcfpIo3hzcQB+AAD///////////////7////+AAAAAXVxAH4ABAAAAQCtDpJpDDX+Bfy0UeIXkigNMp7evQ5MML2Bsphg1sk3+JwpS6u86wdXMmrhoa/HrFjTZ7zZx2yCOL8WzMMzUh3NGuHE2fKi3xrGLN9y1VjGHul8+5NbTt8lxUKccOGytwbXZ7lym4jQEsut/h5gyOcRoFXjHceskStlfJ++gKhpTP/acaxAijvJZ1IRlD6Ydp4ryQNVXujNZFS6fK36TiJ/I3qnvxfaK4EylaISPU6eZa1E+qSwN1gQs1FQWigQ82DMLYj0w9jW8/mjNRpbEs7l1wBJgN5WCWJmqweA6vK6kCEq76ubRAnIRf76nGhpmXuT0oxDEVpXzy2MV+Y21HTheA==";
public static void main(String[] args) throws Exception {
byte[] binary = Base64.decode(FROM_QUESTION);
ByteArrayInputStream bais = new ByteArrayInputStream(binary);
BufferedInputStream bis = new BufferedInputStream(bais, 16);
ObjectInputStream ois = new ObjectInputStream(bis);
BigInteger modulus = null;
BigInteger privExp = null;
while (true) {
bis.mark(16);
if (bis.read() == -1) {
bis.reset();
break;
}
bis.reset();
Object o = ois.readObject();
if (o instanceof BigInteger) {
BigInteger bi = (BigInteger) o;
if (modulus == null) {
modulus = bi;
} else if (privExp == null) {
privExp = bi;
}
}
}
KeyFactory rsaKeyFactory = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(modulus,
privExp);
PrivateKey privateKey = rsaKeyFactory
.generatePrivate(rsaPrivateKeySpec);
BigInteger guessedPubExp = BigInteger.valueOf(0x010001);
RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus,
guessedPubExp);
PublicKey publicKey = rsaKeyFactory.generatePublic(rsaPublicKeySpec);
PEMWriter pemWriter = new PEMWriter(new PrintWriter(System.out));
pemWriter.writeObject(privateKey);
pemWriter.writeObject(publicKey);
pemWriter.flush();
test(privateKey, publicKey);
}
private static void test(PrivateKey privateKey, PublicKey publicKey)
throws NoSuchAlgorithmException, InvalidKeyException,
SignatureException {
Signature rsa = Signature.getInstance("SHA512withRSA");
rsa.initSign(privateKey);
byte[] sig = rsa.sign();
rsa.initVerify(publicKey);
boolean verified = rsa.verify(sig);
// prints true for this key pair
System.out.println(verified);
}
}
(note: this doesn't even comply with my own code practices)
Which will result in:
-----BEGIN RSA PRIVATE KEY-----
MIICHwIBAAKCAQEAr80ULi7+ptoVW5In5LdTfq5oVeLMdXwO9irZIkX9eKmI8qBx
jetVwpifYE8M/z8ee3Fe2i9PJ6WIJQ/PHOrCUwAJA7iSVQEYAyQwF7Np3BRIlaqP
Pr631o73IEZW8rWqzlI9KoS5R0Yly6zop7TLn23gKFSs1FBxGi6LCjMe/7fxO7tt
7/p/AUPQ48CNNYzGCu3Ovr6hNIxuBBzTqIHQTUFR1WuGk7fm6KHlgZIelAsWY8hB
6QC6B3/1xALodjpl8kSErwRLdjPncdNjT6sZSOd6ucmBGu+p/3dsV49umtdhQacC
ocpt6uCVmkgM+64p/ldl2WMSaeFKYoYgcfpIowIBAAKCAQEArQ6SaQw1/gX8tFHi
F5IoDTKe3r0OTDC9gbKYYNbJN/icKUurvOsHVzJq4aGvx6xY02e82cdsgji/FszD
M1IdzRrhxNnyot8axizfctVYxh7pfPuTW07fJcVCnHDhsrcG12e5cpuI0BLLrf4e
YMjnEaBV4x3HrJErZXyfvoCoaUz/2nGsQIo7yWdSEZQ+mHaeK8kDVV7ozWRUunyt
+k4ifyN6p78X2iuBMpWiEj1OnmWtRPqksDdYELNRUFooEPNgzC2I9MPY1vP5ozUa
WxLO5dcASYDeVgliZqsHgOryupAhKu+rm0QJyEX++pxoaZl7k9KMQxFaV88tjFfm
NtR04QIBAAIBAAIBAAIBAAIBAA==
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr80ULi7+ptoVW5In5LdT
fq5oVeLMdXwO9irZIkX9eKmI8qBxjetVwpifYE8M/z8ee3Fe2i9PJ6WIJQ/PHOrC
UwAJA7iSVQEYAyQwF7Np3BRIlaqPPr631o73IEZW8rWqzlI9KoS5R0Yly6zop7TL
n23gKFSs1FBxGi6LCjMe/7fxO7tt7/p/AUPQ48CNNYzGCu3Ovr6hNIxuBBzTqIHQ
TUFR1WuGk7fm6KHlgZIelAsWY8hB6QC6B3/1xALodjpl8kSErwRLdjPncdNjT6sZ
SOd6ucmBGu+p/3dsV49umtdhQacCocpt6uCVmkgM+64p/ldl2WMSaeFKYoYgcfpI
owIDAQAB
-----END PUBLIC KEY-----
Verification: true
So there you have it, an RSA key pair of 2048 bit minus the CRT parameters. Note that the other party should at least have used RSAPrivateKey.getEncoded()
and RSAPublicKey.getEncoded()
instead of object serialization.
Upvotes: 2