PEMException: unable to convert key pair: null - java

I'm trying to run the following program:
import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.openssl.PEMKeyPair;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.KeyPair;
import java.security.KeyFactory;
import java.io.StringReader;
import javax.crypto.Cipher;
import java.util.Base64;
import java.security.interfaces.RSAPrivateKey;
public class Test
{
public static void main(String[] args) throws Exception
{
Security.addProvider(new BouncyCastleProvider());
String key = "-----BEGIN RSA PRIVATE KEY-----" +
"MIIBOgIBAAJBAKj34GkxFhD90vcNLYLInFEX6Ppy1tPf9Cnzj4p4WGeKLs1Pt8Qu" +
"KUpRKfFLfRYC9AIKjbJTWit+CqvjWYzvQwECAwEAAQJAIJLixBy2qpFoS4DSmoEm" +
"o3qGy0t6z09AIJtH+5OeRV1be+N4cDYJKffGzDa88vQENZiRm0GRq6a+HPGQMd2k" +
"TQIhAKMSvzIBnni7ot/OSie2TmJLY4SwTQAevXysE2RbFDYdAiEBCUEaRQnMnbp7" +
"9mxDXDf6AU0cN/RPBjb9qSHDcWZHGzUCIG2Es59z8ugGrDY+pxLQnwfotadxd+Uy" +
"v/Ow5T0q5gIJAiEAyS4RaI9YG8EWx/2w0T67ZUVAw8eOMB6BIUg0Xcu+3okCIBOs" +
"/5OiPgoTdSy7bcF9IGpSE8ZgGKzgYQVZeN97YE00" +
"-----END RSA PRIVATE KEY-----";
String ciphertext = "L812/9Y8TSpwErlLR6Bz4J3uR/T5YaqtTtB5jxtD1qazGPI5t15V9drWi58colGOZFeCnGKpCrtQWKk4HWRocQ==";
// load the private key
PEMParser pemParser = new PEMParser(new StringReader(key));
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
KeyPair keyPair = converter.getKeyPair((PEMKeyPair) pemParser.readObject());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPrivateCrtKeySpec privateKeySpec = keyFactory.getKeySpec(keyPair.getPrivate(), RSAPrivateCrtKeySpec.class);
RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);
// load the ciphertext
byte[] cipherBytes = Base64.getDecoder().decode(ciphertext);
// perform the actual decryption
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] plaintext = cipher.doFinal(cipherBytes);
}
}
It was able to compile without issue but when I try to run it I get the following error:
Exception in thread "main" org.bouncycastle.openssl.PEMException: unable to convert key pair: null
at org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.getKeyPair(Unknown Source)
at Test.main(MyTest.java:35)
Caused by: java.lang.NullPointerException
... 2 more
So I guess getKeyPair doesn't like (PEMKeyPair) pemParser.readObject(). Well that's what I got from Get a PrivateKey from a RSA .pem file...

I had a similar issue and was able to solve it by altering the key from
-----BEGIN RSA PRIVATE KEY-----
.....content here.....
-----END RSA PRIVATE KEY-----
to:
-----BEGIN EC PRIVATE KEY-----
.....content here.....
-----END EC PRIVATE KEY-----
Since you are working with an RSA instance and not an elliptic curve (EC) this might not be the source of your problems but maybe it helps someone.

Related

RSA private key in PEM Format

My generated RSA keys are invalid in external systems.
I've generated RSA Keys using Java.
KeyPairGenerator generator = null;
try {
generator = KeyPairGenerator.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
generator.initialize(2048);
KeyPair pair = generator.generateKeyPair();
StringBuilder sbPrivate = new StringBuilder();
sbPrivate.append("-----BEGIN RSA PRIVATE KEY-----\n");
sbPrivate.append(Base64.getEncoder().encodeToString(pair.getPrivate().getEncoded()));
sbPrivate.append("\n-----END RSA PRIVATE KEY-----\n");
StringBuilder sbPublic = new StringBuilder();
sbPublic.append("-----BEGIN RSA PUBLIC KEY-----\n");
sbPublic.append(Base64.getEncoder().encodeToString(pair.getPublic().getEncoded()));
sbPublic.append("\n-----END RSA PUBLIC KEY-----\n");
In result I've got:
-----BEGIN RSA PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCtundURFaFhoiPmaNbfHUoWQLcohydlwl6riLu64QL/Oyl8V4gqGT2l/OiC2xUMrP8Q+iKWbBaDSr3dmXS5NBiv5QAPJR3GtGE8gP5zRpISeV8uPMvU2Ao5PaEsOazYCITVDAj+b+kDQ25Aq052CTIwyhAnc0OPsAySNYpNgZKpHL0dyY0vHE9hbwN6qc76w3QlC+Oo0swPqoIO3Tk1VnsgV3+5c5vSJwHYTLENfSL8ueVxn79RRYMkIFyFcXxA7LqIp5Byr430f9Zm+jTR2yLSPndMseetDCsEmouzXR8pILMxTFdmhisv6YNPGE5SBh0CUe4thgqT2bqEEbwUscNAgMBAAECggEAFNy1g7sJINO9BnGOumfBseyueUxGX25Jxx+uNj62BrKCwJKxmP5f0XUB3s28XogQMRT+kc6fbNDz/e+L3r13gMQ8w6KCuaLQ0kQ10gOdSl0FX+rd2SsL+x0ztU+BBL1gmi2b8lYFe2/N3A/EOZQJJsq4xLmubC2A6wjwHtbL/p551lvw70hAqIrCV0PZkB+Qja6fycrjC++FFzVAPNmA5PCHxbNX3Jp4t9U3O6SrDq8sbk2F4bApJ/C7hs+JDE5DIzTyU6jxJUf6bxaYOqAfTEkuuM+NrFi29z/si30mL5pA+fuPlkB41xXJhMizPCbOcyHKLnKoc6nIc8Dfin69QQKBgQC5g4Lr59kvhGJVNsxZUJX0TZTJ5c0m/cwWt4cjB46gnJI7a9Quiw9dNxpQO/Hd56geXGWm9IFq87guAUa49+rcWx6KlaKCZqtNKKtFJ3WIon85Yqoyxvnmk/UmCYZZ9Y0Qk+LTaWmNk3tuBkyPOWSSYqmLBejcskweuBfX0p0TOQKBgQDvvJ9qiHEErHiZEEwkizTPLQTQZ6CScTWVX5djKpKWwKHCSEgoH3rYVq/q5Y+pfzO4Mjk30vXuGken9vy5tHvwNV1JEJBt1rWizZBxJakaFrPsyGXj4/Ihf+qojEXxc8FbUHuGjj48IjlVrLID747dYGkgrwBF3hR0Dw6C6frudQKBgCoxqUNytklCeQMctZnS5GhuhNru85xcuWCpWYk0HNKXCgON4PK9Gj9/WvLIz5hDKk/NgClbD1x+FnQQQj+r07VO3EF1C0NRisC/8USHVwo+u2UX9dIaw5gYKvf9zpsDaJROrpabMTDMTJSXxi4FRcStwBYov/ACdaG/CV1DQAqxAoGAEdF8K8feVpGXGRFMB39NOoTHEdJR7fB6IhMLxnQYlxnULAOBUXIdiEzRIG1VgyyQJIWfGRYV70+GueYynH7co1rkBxUzFubZczNCJBa/fc/oKZYvdIOxsGm4gDSE0lBfM7FErRiPaZrFlieSx5YbkTqkNaisJYU/Ee04j+RiIS0CgYBGi63jlyS2YEHlewJUxP29KLIf4G8wGKIAaXi19DX8eU7b+4uniAGwhyvL1Sbe1jcePJgjBA4OXSiUcCDPaNa0rgrVeeW2xeh4ZPmH3tXo1ex5+saIwSDng424K5UPp/rs9oH3CVNe0vHxjrnrQX5VaRcv7ZU+DO6x9VeWMPOXsQ==
-----END RSA PRIVATE KEY-----
-----BEGIN RSA PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArbp3VERWhYaIj5mjW3x1KFkC3KIcnZcJeq4i7uuEC/zspfFeIKhk9pfzogtsVDKz/EPoilmwWg0q93Zl0uTQYr+UADyUdxrRhPID+c0aSEnlfLjzL1NgKOT2hLDms2AiE1QwI/m/pA0NuQKtOdgkyMMoQJ3NDj7AMkjWKTYGSqRy9HcmNLxxPYW8DeqnO+sN0JQvjqNLMD6qCDt05NVZ7IFd/uXOb0icB2EyxDX0i/LnlcZ+/UUWDJCBchXF8QOy6iKeQcq+N9H/WZvo00dsi0j53TLHnrQwrBJqLs10fKSCzMUxXZoYrL+mDTxhOUgYdAlHuLYYKk9m6hBG8FLHDQIDAQAB
-----END RSA PUBLIC KEY-----
But when I'm trying to use this keys here
https://kjur.github.io/jsrsasign/sample/sample-rsasign.html
https://www.devglan.com/online-tools/rsa-encryption-decryption
These keys are invalid.
Where could be a problem?
THe keys are not being written to standard PEM formats: PKCS8 & X.509 respectively.
The following works but the keys need to be tested on https://8gwifi.org/PemParserFunctions.jsp. This shows the PEMs are good.
However, neither of the sites you suggested can process them.
import java.io.StringWriter;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.openssl.jcajce.JcaPKCS8Generator;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
public class Whatever {
public static void main (String[] args) throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.generateKeyPair();
StringWriter writer = new StringWriter();
try (JcaPEMWriter w = new JcaPEMWriter(writer)) {
w.writeObject(new JcaPKCS8Generator(kp.getPrivate(), null));
}
PemWriter pemWriter = new PemWriter(writer);
pemWriter.writeObject(new PemObject("PUBLIC KEY", kp.getPublic().getEncoded()));
pemWriter.flush();
pemWriter.close();
System.out.println (writer.toString());
}
Output:
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCXHK07oaqx8fnY
r3UbfUS6HRXQFRvQ0J8qqzgq+UH4ZqtgxV44ciSOwzL65E2aZrixXxB+s7Kbbw1q
R0oUNvay8QhMlmwUZwXjCZbeNbQI8LXoXSU1l9xx2GZ7BS3/huFGHSyGzjrSYJdJ
cZKOYij26aCPIx7VYEeIUmPAbkCA1VVUhaOic81aQAdhqrKjqpBcYTwYW4YF2zcy
Dx8YLrRLJbjFzM94eg9oErqIsptyZ83daoNytVTbijzDoXAmkHrx58NfZnuJ0JfH
UKGZiMlt6fBAqDR3+Dls6hemJA+VxCO2dKBDp2vSGfIDc1mr1kQozFK3JqFINcWI
537vnPWVAgMBAAECggEAA/VAagMFx3k/p/05MMdi8l9afSkJtw+Of7hc4APyhlOw
HPiGdi2H3MUVnoHg23thzo7feHtzS+7Id+vBRQ7HKZrhHVpvnx2EsgnurZ1+p0ug
xCLpG4KBsmoD4yiDUtcBAGG5aG2El709G94cQ9uj2DXN2rnwL+VrR5GQOHqFeNUI
rTKUG4lwCPcvPOvnpdYj2jv4oj4uO2cbmgbZThcl4KdHK/Eo/jHr0UOhiT5J9ocm
RKryYYjEXE/t57tR2e0Rsel74fTmcgNygiixMjKDC1cmqX4R+g67m1gfR+/+SXR8
S9f9VzcwugcTnxIhke3TRta53QgfPNLOidpMM1tLwQKBgQC9faOxEVJ2KTQaAAMw
Nx8bBxhev5mifi+f8d14ERkG7XFb4SzPeUY29oB0KVxDyBwR8rgNars+GpUnquZv
91PVs5fYD3W+HwtOD/UOL0z3UtKnNI8nvtK08ru0PFDVzwzqEapy8dLkmbG556GP
HZ5WVn+8QeTX7GqbSU3xtPp21QKBgQDMJpTMzneQ+GrupU1lzdlD8GKF2RbsZ0Ui
rtIx4UYgIQV0lbvPhneJrGy16woOBUZ7jkCEDXKqofGumwCVfhpjjYzIqPfZzXaa
t5a6l2cLuwt0JnjluwqmIfWf1z+GdqCxgqUwdUgzxcPmzxcHwOCX1YFQQ8WONd6s
Id9DfAFjwQKBgQCLsKhQq11oAD4JgMLY83m52gQsLQEcWfvP5GSI08noYnhz7E61
cEjD0fqmJ6t9yHJxBMaMFYeNY9lbEdCo7+JcovWocNUy3/3cgUT9PP93QBZM7yEt
gq4geOTJHMHWrLlvgLBv5je7EFaFnu1p7MLCESg/ZzBFwWJhsauFKQ6PNQKBgFDc
PzfX15f+LSyVINDf9dxpDD0DvYapaMLSB8Nl/Qagza5d2GPcWOCZAP4VOIhRIpex
wnALe42GU1nbXyHXLtCbslWQR4tnTED/0p3ZdiE5VtIMovorWY5wCP/km+7Acemd
W5yT96M6A9wZzn9tsAezs2J9VXR8ddQsHmh2Z36BAoGBAIkFBge0QbWZGYCr3uk9
K0AhZUekGSzhakqp60XQs5kw8zb+TllCRxtYsQlyaHp1M8AH3Di/Uw+EhBt6h4Uw
fAPCZRg8vdG8Hp26PwXxybZ/M9u7NaKJ0BT4AwKKtZTUxZVxz/kPhdHT+MpoQqJf
JuzuwXVAAcl1GME2OiqkZhww
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlxytO6GqsfH52K91G31E
uh0V0BUb0NCfKqs4KvlB+GarYMVeOHIkjsMy+uRNmma4sV8QfrOym28NakdKFDb2
svEITJZsFGcF4wmW3jW0CPC16F0lNZfccdhmewUt/4bhRh0shs460mCXSXGSjmIo
9umgjyMe1WBHiFJjwG5AgNVVVIWjonPNWkAHYaqyo6qQXGE8GFuGBds3Mg8fGC60
SyW4xczPeHoPaBK6iLKbcmfN3WqDcrVU24o8w6FwJpB68efDX2Z7idCXx1ChmYjJ
benwQKg0d/g5bOoXpiQPlcQjtnSgQ6dr0hnyA3NZq9ZEKMxStyahSDXFiOd+75z1
lQIDAQAB
-----END PUBLIC KEY-----
Results from 8gwifi.org
Private key:
Private Key algo RSA
Private Format PKCS#8
ASN1 Dump
RSA Private CRT Key [f9:3d:bb:ce:14:eb:b6:f4:68:c0:69:54:a8:47:da:56:78:6d:d2:ad]
modulus: 971cad3ba1aab1f1f9d8af751b7d44ba1d15d0151bd0d09f2aab382af941f866ab60c55e3872248ec332fae44d9a66b8b15f107eb3b29b6f0d6a474a1436f6b2f1084c966c146705e30996de35b408f0b5e85d253597dc71d8667b052dff86e1461d2c86ce3ad260974971928e6228f6e9a08f231ed56047885263c06e4080d5555485a3a273cd5a400761aab2a3aa905c613c185b8605db37320f1f182eb44b25b8c5cccf787a0f6812ba88b29b7267cddd6a8372b554db8a3cc3a17026907af1e7c35f667b89d097c750a19988c96de9f040a83477f8396cea17a6240f95c423b674a043a76bd219f2037359abd64428cc52b726a14835c588e77eef9cf595
public exponent: 10001
Public key:
Algo RSA
Format X.509
ASN1 Dump
RSA Public Key [a6:cc:21:c6:b2:98:92:7a:96:d6:5b:ac:38:32:0c:dc:a3:1c:42:e5]
modulus: 9c3eac15e0897fd6d1ecf1ff622b0fc0278f31496d10babf869fc39b8d3d5d4ff211b8014c8ff03149c7fb68ee39361e0a2ace075d1b73f42b15585a2d5de01d6caf48bf96bf4b9f75679988b5c09c808d75d889090bce53ee6c78d5283f0e102af14042064ba20b235a6dae6a32529d21ac9150ade3c81a595ac888ee0e419564493c57ad43649de9d727d6f66d76a6fc1b75c9ad44d6dd7f6ff21367fd375908df1b05e072da98cadbc01c2defe78d6cf68e77276b969ffa4e049736d39f007795b2cea3d11f303581b97e5e29cab3ce57e54e4f030262542b12c82164346c099a6b823edac78a9c198b96b1e637eb6fbd4f962963d9539776b476cd4ec539
public exponent: 10001
There is a dependency on Bouncy Castle as follows:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.56</version>
</dependency>

How do I encrypt string in nodejs with public generated by java

I want to encrypt my password in angular side before sending it to Springboot API. My idea is to do:-
Generate public key and private key in java
Do a base64 encoding on both public key and private key
Use encoded public key in node (angular) side, this will be used for encryption
Use encoded private key in springboot rest api, this will be used for decryption
Below is my java code which generates, encrypts and decrypts password
RSAKeyPairGenerator.java
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
public class RSAKeyPairGenerator {
private static String privateKeyString = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALyR1WRqVBuvdmXmgrcZ4VMY4hIFTYt63NGEN9atlgnngNliMasvzBofnjRtk5mukezUKujtON6mPnAjKJoEDdiaw3Rk0hKvgW5MszyUBE5bLThexVLbi+nQYSf2GSvd0fjdZn6KjhgVOdbYe+JduU/iPD3/Ti5p+w3MewgZpy2RAgMBAAECgYAqWdqCXfsb6LF/u2C6PN7Faf5EK9q5q9NyXu6nkX70JIFk0U/0cZy2dUlz3vRafMGbXh9xBu5R2yaEyvCwfp6ZF26A8MbS/IaI53LMKmyclhES2f3tZLKUPkg6fntz+e6e/6oSDdQPHP3J2QrpuwzyW+UZJQmmYYj7f9sq/+dawQJBAOnkHWkLuIZNIgLzV0TuHA6fcOXrqrSlS1/Q0qLyaQEZOObocXDvWaCSP+8RXiqZSwAnMJbrGHQA5ULXLWI4GjkCQQDOZP6bfn2VV3m8JSlYL9Uz4TrRYb8Qe3/mohhMsyDB7Ua/6d9BV7JZgbYiXP0utobKVWLxD49OFMkgEs20qY4ZAkB4dJsQ9pBZ2m+hxWE0hsy8WzDxuKV504c2GX3hnaamgi7j/OIvn5UxNSDoJrGwjrIpqgVENF+rnqpz+g3Nf8dBAkBV/op+6yMUGFBmbe1eCwAAD7XcC6f6DBrsU1lgi7n4Uw6JY75bkViEJqFmi+wJjI94uj7xRZRl6g8qx+rhfUvxAkEArD1we6ZLTWz73D8z+4Boj7Su7b5LhfgvXVL5V4Zdog3X58pHK+dYppapDh5KjZZdor+y/6uz1PqIs2dmFy/xtQ==";
private static String publicKeyString = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8kdVkalQbr3Zl5oK3GeFTGOISBU2LetzRhDfWrZYJ54DZYjGrL8waH540bZOZrpHs1Cro7Tjepj5wIyiaBA3YmsN0ZNISr4FuTLM8lAROWy04XsVS24vp0GEn9hkr3dH43WZ+io4YFTnW2HviXblP4jw9/04uafsNzHsIGactkQIDAQAB";
private static PrivateKey privateKey;
private static PublicKey publicKey;
public void generateKeys() throws NoSuchAlgorithmException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair pair = keyGen.generateKeyPair();
RSAKeyPairGenerator.privateKey = pair.getPrivate();
RSAKeyPairGenerator.publicKey = pair.getPublic();
}
public void readKeys() throws NoSuchAlgorithmException, InvalidKeySpecException {
KeyFactory kf = KeyFactory.getInstance("RSA");
byte [] encoded = Base64.getDecoder().decode(privateKeyString);
PKCS8EncodedKeySpec keySpec1 = new PKCS8EncodedKeySpec(encoded);
RSAKeyPairGenerator.privateKey = kf.generatePrivate(keySpec1);
encoded = Base64.getDecoder().decode(publicKeyString);
X509EncodedKeySpec keySpec2 = new X509EncodedKeySpec(encoded);
RSAKeyPairGenerator.publicKey = kf.generatePublic(keySpec2);
}
public static void main(String[] args) throws NoSuchAlgorithmException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException {
RSAKeyPairGenerator keyPairGenerator = new RSAKeyPairGenerator();
// Next line is for testing with encrypted text generated by nodejs code with genrated keys
// keyPairGenerator.generateKeys();
keyPairGenerator.readKeys();
System.out.println("-----Private----------");
System.out.println(Base64.getEncoder().encodeToString(privateKey.getEncoded()));
System.out.println("Encoding : "+ privateKey.getFormat());
System.out.println("----------------------");
System.out.println("-----Public----------");
System.out.println(Base64.getEncoder().encodeToString(publicKey.getEncoded()));
System.out.println("Encoding : "+ publicKey.getFormat());
System.out.println("----------------------");
String secretMessage = "Test";
System.out.println(secretMessage);
Cipher encryptCipher = Cipher.getInstance("RSA");
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] secretMessageBytes = secretMessage.getBytes(StandardCharsets.UTF_8);
byte[] encryptedMessageBytes = encryptCipher.doFinal(secretMessageBytes);
// Next lines are for testing decryption with encrypted text generated by nodejs code with generated keys
// byte[] encryptedMessageBytes = "B��u���<⌂׷�lǚm0�W������1�%EN�7��‼��l��l�<�����k;�������GĦ9D8��Z��I�Oɺ♫��→P'�§�{k�Ɋ+-}?��rZ".getBytes();
// byte[] encryptedMessageBytes = Base64.getDecoder().decode("woboAUytDXJLlKm7zbqNdxVORG+kio9kZxvMPOHruQfxwNEx7SVFTsw3oeETqbRs4NZskjzO2Nzjyms73vv758Dcy0fEpjlEOKmrWuG62knOT8m6DqGDGlAn1hXpe2u6yYorLX0/6fhyWg1C/JR1sbaKPH/Xt+Fsx5ptMONX0uw=");
System.out.println(new String(encryptedMessageBytes));
Cipher decryptCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedMessageBytes = decryptCipher.doFinal(encryptedMessageBytes);
String decryptedMessage = new String(decryptedMessageBytes, StandardCharsets.UTF_8);
System.out.println(decryptedMessage);
}
}
This gives me following output
-----Private----------
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMv+t+D6/7ZY6m+CjD97NB989P2YjmGcE2yHUokyjmxVi/SxIu9MboiVNewR+mFjTFYPGgMWHz1/XeVGlinjN/5+0fdiO/JEvEUilFmkkIF3My11I09b9NZ9RJmpCNCbqOg7NSt6VD8IC/w19N25xwcofc3qbgfEjKSs0CgxfahrAgMBAAECgYEAiyLlEBKiryDeZchJGFNULdXw07dmBbWKmg+CgAl3kvSWTQM0rLsY+Rese6OXfy1XN6t9NnW0QSHKTUNj0JYl7btKEblVHERbjwavUe83tcNIc3o0xrGoBAzma14ZicPYm70JWixTO778lm5AXKl504+oOQyVYmfgXcevPXwdIkECQQDvO3DBuu6wp5nbwR4t0736HOH9jVIjJOS8oABUARDhNt1fkb8uEptDr5EomVRMqarJMAjSMpYxrUCpvgtf4nZ5AkEA2ksDr8pbbFvZPaAe0F43LmJtFM3PvCz87S93p20YjwVMmGV17sJ5t7a26HtubgRLEWq4z6rxq2oXPv4y1lstAwJAbj9cVUtKWIrEcutqdwAPmsXYt7p60ctcxjiOLihXmRJprnNCQX89olG0eZs/qBzAofrK9eNuJ/KJzC/SmhuJMQJAAz9gc6oQCCGprrgGHVV5frAqLUgOkh8dOC4fmpcN6XrLs+y2f3HXO7t1JypG704TC9RJoZVKeSFf7Sj8+qFqnwJBALRiQc9SG5Ht5TLo12W4l3bRaxpbo597BgKRjz3hqiySdqjZA9Qe84qmEKveZ9eWehbfqwzKmCbW43I1ZEFZ95o=
Encoding : PKCS#8
----------------------
-----Public----------
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL/rfg+v+2WOpvgow/ezQffPT9mI5hnBNsh1KJMo5sVYv0sSLvTG6IlTXsEfphY0xWDxoDFh89f13lRpYp4zf+ftH3YjvyRLxFIpRZpJCBdzMtdSNPW/TWfUSZqQjQm6joOzUrelQ/CAv8NfTduccHKH3N6m4HxIykrNAoMX2oawIDAQAB
Encoding : X.509
----------------------
Test
�N::�`��\A���ƈ�~��5s���
�0�I�C�uƹx2�Z&Kں�"ьC�$
q��K���h�^<�5�E�Ɨ0B�͒Z�{��EDbDH�.��#:�e��h~j���������q�c��R�
Test
In the Nodejs side I am using the above public to encrypt my text.
index.js
const crypto = require("crypto");
var pubkey = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL/rfg+v+2WOpvgow/ezQffPT9mI5hnBNsh1KJMo5sVYv0sSLvTG6IlTXsEfphY0xWDxoDFh89f13lRpYp4zf+ftH3YjvyRLxFIpRZpJCBdzMtdSNPW/TWfUSZqQjQm6joOzUrelQ/CAv8NfTduccHKH3N6m4HxIykrNAoMX2oawIDAQAB\n-----END PUBLIC KEY-----";
var plaintext = "Test"
var buffer = new Buffer.from(plaintext, "utf8");
var enc = crypto.publicEncrypt(pubkey, buffer);
var bs64 = enc.toString('base64');
console.log(enc.toString());
console.log(enc.toString('base64'));
this gives me following output
B��u���<⌂׷�lǚm0�W������1�%EN�7��‼��l��l�<�����k;�������GĦ9D8��Z��I�Oɺ♫��→P'�§�{k�Ɋ+-}?��rZ
woboAUytDXJLlKm7zbqNdxVORG+kio9kZxvMPOHruQfxwNEx7SVFTsw3oeETqbRs4NZskjzO2Nzjyms73vv758Dcy0fEpjlEOKmrWuG62knOT8m6DqGDGlAn1hXpe2u6yYorLX0/6fhyWg1C/JR1sbaKPH/Xt+Fsx5ptMONX0uw=
Now I tried using both the strings in java side for decryption.
When I try decoding the string, it gives me following error
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Data must not be longer than 128 bytes
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:346)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:391)
at javax.crypto.Cipher.doFinal(Cipher.java:2168)
at com.mindtree.starr.wsr.RSAKeyPairGenerator.main(RSAKeyPairGenerator.java:90)
And, when I try decoding the base64 string, it gie me following error
Exception in thread "main" javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:379)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:290)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:365)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:391)
at javax.crypto.Cipher.doFinal(Cipher.java:2168)
at com.mindtree.starr.wsr.RSAKeyPairGenerator.main(RSAKeyPairGenerator.java:90)
What am I doing wrong?
The problem was clearly described in the first comment and the solution is in second comment.
Correct transformation string for Cipher instance that worked for me is RSA/ECB/OAEPWithSHA-1AndMGF1Padding
So below instantiation for decryption Cipher works perfectly.
Cipher decryptCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");

Decrypt file using .pfx certificate in Java

I have an .pfx file and a password for the file.
I would like to decrypt a RSA encrypted file using Java.
Basically the same approach like here (c#), but in java:
https://stackoverflow.com/a/37894914/13329087
is this possible?
my approach so far:
byte[] file = Files.readAllBytes(Paths.get("C:/file.fileinfo"));
String pfxPassword = "pwd";
String keyAlias = "pvktmp:1ce254e5-4620-4abf-9a12-fbbda5b97fa0";
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(new FileInputStream("/keystore.pfx"), pfxPassword.toCharArray());
PrivateKey key = (PrivateKey)keystore.getKey(keyAlias, pfxPassword.toCharArray());
Cipher cipher = Cipher.getInstance(key.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, key);
System.out.println(new String(cipher.doFinal(file)));
this produces an Error:
Exception in thread "main" javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:379)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:290)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:365)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:391)
at javax.crypto.Cipher.doFinal(Cipher.java:2168)
Unfortunately you didn't provide the keystore *pfx-file nore the encrypted file so I had to setup my own files. If you like to run my example with my files you can get them here:
https://github.com/java-crypto/Stackoverflow/tree/master/Decrypt_using_pfx_certificate_in_Java
Your sourcecode doesn't show the inputStream-value in
keystore.load(inputStream, pfxPassword.toCharArray());
and I used the direct loading of the keystore:
keystore.load(new FileInputStream("keystore.pfx"), pfxPassword.toCharArray());
Using my implementation I can sucessfully decrypt the encrypted file ("fileinfo") with this console output:
https://stackoverflow.com/questions/62769422/decrypt-using-pfx-certificate-in-java?noredirect=1#comment111047725_62769422
RSA decryption using a pfx keystore
The quick brown fox jumps over the lazy dog
To answer your question: Yes it is possible to decrypt a RSA encrypted file with a pfx-keystore. The error you see in your implementation seems to result that the key(pair) that was used to encrypt (the public key in the certificate) has changed in the meantime and you are trying to decrypt with a (maybe new generated) other private key (with the same alias). To check this you need to provide the keystore and the encrypted file...
Here is the implementation I'm using (I just edited the inputStream-line):
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.security.cert.CertificateException;
public class MainSo {
public static void main(String[] args) throws IOException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, CertificateException {
System.out.println("https://stackoverflow.com/questions/62769422/decrypt-using-pfx-certificate-in-java?noredirect=1#comment111047725_62769422");
System.out.println("RSA decryption using a pfx keystore");
//byte[] file = Files.readAllBytes(Paths.get("C:/file.fileinfo"));
byte[] file = Files.readAllBytes(Paths.get("fileinfo"));
// password for keystore access and private key + certificate access
String pfxPassword = "pwd";
String keyAlias = "pvktmp:1ce254e5-4620-4abf-9a12-fbbda5b97fa0";
// load keystore
KeyStore keystore = KeyStore.getInstance("PKCS12");
//keystore.load(inputStream, pfxPassword.toCharArray());
keystore.load(new FileInputStream("keystore.pfx"), pfxPassword.toCharArray());
PrivateKey key = (PrivateKey) keystore.getKey(keyAlias, pfxPassword.toCharArray());
Cipher cipher = Cipher.getInstance(key.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, key);
System.out.println(new String(cipher.doFinal(file)));
}
}

Given a public key string, how to create an instance of RSAPublicKey

I have an actual public key string like:
-----BEGIN PUBLIC KEY-----
flajeleofancncMFLDFJOEEFJC9209ueq33rlsjfa3B ...
-----END PUBLIC KEY-----
In order to create an auth0/java-jwt-library Algorithm to sign my JWT, I need a java.security.interfaces.RSAPublicKey-implementation instance. How would I go about creating that instance given public key string? If it helps, I also have the private key string.
I'm just starting out. So, I'm open to simpler ways to signing my JWT.
import java.security.KeyFactory;
import java.security.spec.X509EncodedKeySpec;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.EncodedKeySpec;
import java.security.interfaces.RSAPrivateKey;
...
String algorithm = "RSA" // for example
KeyFactory kf = KeyFactory.getInstance(algorithm);
String publicKeyStr = "-----BEGIN PUBLIC KEY-----f24Defosfvak-----END PUBLIC KEY-----"
EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyStr.getBytes());
RSAPublicKey publicKey = kf.generatePublic(keySpec);

Decrypting a Base64 string encoded using RSA using Base64 encoded CRT components

so I've found myself having to decrypt a string given to me via an API. I know it's been Base64 encoded, and then encrypted with an RSA key (although I'm not sure in what order). I've been given the Modulus, public and private exponents, and the primes. The following code was my (truncated) attempt, and it's throwing me an "javax.crypto.BadPaddingException: Decryption error" on the final line. No idea where to go from here, any help would be appreciated :)
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
public static final String RSAKeyFactory = "RSA";
public static final String RSAKeyAlgorithm = "RSA/ECB/PKCS1Padding";
public static final String UTF_8 = "UTF-8";
byte[] mod = Base64.getDecoder().decode("3dlF3Frvwmuet+gM/LX8EQBI...");
BigInteger modulus = new BigInteger(1,mod);
byte[] prive64 = Base64.getDecoder().decode("YwTJhmqOS58PJzhhvuREI...");
BigInteger privExp = new BigInteger(1,prive64);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(new RSAPrivateKeySpec(modulus, privExp));
byte[] cipherBytes = Base64.getDecoder().decode("VdznCyJeYukJahmHsbge...");
Cipher cipher = Cipher.getInstance(RSAKeyAlgorithm);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] plainData = cipher.doFinal(cipherBytes);
Cheers

Categories