Generating Rsa Keys in Pkcs#1 Format in Java

Read RSA private key of format PKCS1 in JAVA

Java does not come with out-of-the-box support for PKCS1 keys. You can however use Bouncycastle

PEMParser pemParser = new PEMParser(new FileReader(privateKeyFile));
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
Object object = pemParser.readObject();
KeyPair kp = converter.getKeyPair((PEMKeyPair) object);
PrivateKey privateKey = kp.getPrivate();

Getting RSA public key from PKCS1 key

You can use BouncyCastle library to achieve this. Your key is in PEM fromat. To read it you can use PEMParser :

private static PublicKey readPublicKey(String path) throws InvalidKeySpecException, NoSuchAlgorithmException, IOException {
PEMParser pemParser = new PEMParser(new FileReader(path));
Object object = pemParser.readObject();
SubjectPublicKeyInfo subjectPublicKeyInfo = (SubjectPublicKeyInfo) object;

RSAKeyParameters rsa = (RSAKeyParameters) PublicKeyFactory.createKey(subjectPublicKeyInfo);

RSAPublicKeySpec rsaSpec = new RSAPublicKeySpec(rsa.getModulus(), rsa.getExponent());
KeyFactory kf = KeyFactory.getInstance("RSA", new BouncyCastleProvider());
return kf.generatePublic(rsaSpec);
}

And then to encrypt with this key :

PublicKey publicKey = readPublicKey("src/main/resources/key.pem");

String dataToEncrypt = "myMessage";
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encrypted = cipher.doFinal(dataToEncrypt.getBytes(StandardCharsets.UTF_8));

Tested with versions : bcpkix-jdk15on and bcprov-jdk15on.

How do I generate RSA key pair in JAVA (in openssl format)

You say 'the' format supported by OpenSSL, but OpenSSL supports multiple formats for (RSA and other) private keys, over a dozen depending how you count.

The particular formats you show, perhaps coincidentally, are the PEM forms of the two formats directly supported by Java crypto, PKCS8-unencrypted for private and 'X.509' (really SubjectPublicKeyInfo aka SPKI) for public, and thus can be created simply:

//nopackage
import java.security.*;
import java.util.Base64;

public class SO43459993SimpleRSAPEM {
public static void main (String[] args) throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048); KeyPair kp = kpg.generateKeyPair();

System.out.println ("-----BEGIN PRIVATE KEY-----");
System.out.println (Base64.getMimeEncoder().encodeToString( kp.getPrivate().getEncoded()));
System.out.println ("-----END PRIVATE KEY-----");
System.out.println ("-----BEGIN PUBLIC KEY-----");
System.out.println (Base64.getMimeEncoder().encodeToString( kp.getPublic().getEncoded()));
System.out.println ("-----END PUBLIC KEY-----");

}
}

Example output:

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCiaT/zBxjS6ZBiCbUBiUFirm3/
xo+A8LY3yBsffu6/6mO0ZwrXNtrHmpQEdld5/XM+k8vKOE+KTfeUwikKOLnHeuzV5qrO4/WZPDyz
ggXGqFrgI3/WT8AqTcAmc21CG92Wx+omVaFyl5j5/Sh6aapYl6TG7qX4NXzEln7Ka70Az39nKtqi
oe7LA5ARjcyOBRPXVg2Oq/O+XSwy/epFHIs83ucswF1j/4Nv4u7juCIQ4+sQFyBUwh2docgH9+Ls
MQ18a2N3khNbhxD9TkehuSGU+/KHd0OmEXVHx6dxEvvVTG+MYuuqBbUxdnReggTdX5bJUXtzf+RM
+6yuqauLNlJDAgMBAAECggEAES0WYUpn2q5u4Z9rMC1m59vQsFM8jANpEf8stykCcPOF9edL4zTe
8GstqkcluzYNwRl6XPmVl+fk/iuGkZksNKeQcpLBj73WFI2lUcq3d6oIaln2xCCNDyxH3QkqDerK
hY7A+armtyrHN/EJHeEc7d+jwpIspVJqzpOn9xpr07DyPJ7EK2IsoupMrJ3OwAmcTWvCnv0465fr
t+OOzlHF6m1fQtTKD7kBcKE9vnGdkNbpOxY6VI0p9e0R3ymITeXWFxebq8G7hMO3baD775t55smv
fbWPl41idvTfwAIgUdfKaEk/28zlXwm6WBt3MBF+jlhbfe3zr5RphxtVdIzIYQKBgQD2iqtSXM6/
PrxM2CNnS0RwVNvDcx6+BwemJk+pkfq1BSuXrLbAs3KPfZ51ASHmV9+8IDuV98nJEEKu4einIGUa
m4GK7gHAq0Ml2ISyXTB+28ZXkgDWqvP044T1RbakBrccDDcbsSiIRznyXkJ2VrTA6+Xufz4rIs2Y
IkYnwBKPkwKBgQCopFGz/7VqPDRd5RL0pm2YWp85M06SD8zss0lbL+EBnAGy/zRjKYMMVlZpuA+Q
6od8idyYoOBNpFgf+SGJTs097yUP7Vk98wk4jDqC0Kbd9VGXlUfWwpFeGlcO6zVTtVC6ShLDyBTL
QoulgIhFmHtjHLsUKhehixhbtDXXfmEAkQKBgDvrR+gkljr0zF8AyNn5+RA0D5VZDUex/bHr7cCQ
shX8w7OBTolXE6i8Jx7Yv5x0DvRyAQlZx7kOMqa+UQUNYoUs9jcF0Xc6KH+yN84ByB+M2o+99GY3
9kK2aUITR2hmGWq/rUUVsXwtk2/MaOrJ9/RLYP6t/jYNp1oqOlK+48PxAoGBAJhTM+leA0Nd9f8J
tsF8wmlnEYLdMQ8FbpguqQfQi3CktXQ0x+D50gEGyy7arlS7Qn3fGH5UccYvt9nJcd1QbFqQ8+0a
+gzWxXFqWD9osBC0UWqV0DnPrPZO3GwBUD23/J8H4UMuKnoeNXzcSDp0rJ6tiN2B1652sR3D/Q4U
fRHBAoGAAseKaXqnBWeSS2RE/FZ7meSC0Wge7dTgkTKRRkJfKuOfLvTs1FB6mNVGkffcjltPuxM3
m79c3lnkD9ub7UZcJtNRY8sv0oM6K6ez1stB9M7qc/ZbgbAE7LzCqgGIywgNVCBAZ4zgSGl0h1SM
/evMdsYTYUXubxolHGq56o+UL4M=
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAomk/8wcY0umQYgm1AYlBYq5t/8aPgPC2
N8gbH37uv+pjtGcK1zbax5qUBHZXef1zPpPLyjhPik33lMIpCji5x3rs1eaqzuP1mTw8s4IFxqha
4CN/1k/AKk3AJnNtQhvdlsfqJlWhcpeY+f0oemmqWJekxu6l+DV8xJZ+ymu9AM9/ZyraoqHuywOQ
EY3MjgUT11YNjqvzvl0sMv3qRRyLPN7nLMBdY/+Db+Lu47giEOPrEBcgVMIdnaHIB/fi7DENfGtj
d5ITW4cQ/U5HobkhlPvyh3dDphF1R8encRL71UxvjGLrqgW1MXZ0XoIE3V+WyVF7c3/kTPusrqmr
izZSQwIDAQAB
-----END PUBLIC KEY-----

Generating RSA keys in Android in PKCS#1 format in Android

Two possible answers.

If you want to go the way you're going, try this to resolve the NoClassDefFoundError.
android eclipse updated and now app crashes when it trys to run

You can also use JSch instead. I have this working reliably on android myself.
RSA Encryption forceclosing before generating public/private keys

Edit: Here's an example of using JSch to generate RSA-type keypairs. I think it's PKCS#1, but I'm not familiar enough with the standard. The relevant javadoc is what I'm going off of.

/**
* Load or generate a RSA keypair to use as a client for the given JSch.
*/
public boolean registerKeyPair(JSch jSch) {
new File(getRootFolder().getAbsolutePath() + "/.ssh").mkdirs();

File privateKey = new File(getRootFolder().getAbsolutePath() + "/.ssh/id_rsa");
File publicKey = new File(getRootFolder().getAbsolutePath() + "/.ssh/id_rsa.pub");
if (!privateKey.exists() || !publicKey.exists()) {
try {
KeyPair keyPair = KeyPair.genKeyPair(jSch, KeyPair.RSA);
keyPair.writePrivateKey(privateKey.getAbsolutePath());
keyPair.writePublicKey(publicKey.getAbsolutePath(), "Machine Shop");
return true;
} catch (JSchException e) {
Log.e("genKeyPair(RSA)", Log.getStackTraceString(e));
} catch (FileNotFoundException e) {
Log.e("genKeyPair(RSA)", Log.getStackTraceString(e));
} catch (IOException e) {
Log.e("genKeyPair(RSA)", Log.getStackTraceString(e));
}
return false;
}

try {
jSch.addIdentity(privateKey.getAbsolutePath());
return true;
} catch (JSchException e) {
Log.w("jSch.addIdentity", Log.getStackTraceString(e));
return false;
}

}

Edit: Assuming Eclipse. Include the JSch jar file in your build path, preferably as a local jar (say in a lib folder). Make sure to check it on the "Order and Export" tab.

Now refresh your project.

Convert RSA Private Key to DER Format in Java

The OpenSSL statement converts the PEM encoded private key in PKCS#1 format into a DER encoded key in PKCS#8 format.

In Java, importing the PEM encoded PKCS#1 private key can be done with e.g. BouncyCastle's PEMParser and JcaPEMKeyConverter (using the bcprov und bcpkix jars). The export can be accomplished with PrivateKey#getEncoded() which returns the DER encoded PKCS#8 private key:

import java.io.FileOutputStream;
import java.io.FileReader;
import java.security.KeyPair;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
...
String inputFile = "<path to PKCS#1 PEM key>";
String outputFile = "<path to PKCS#8 DER key>";
try (FileReader fileReader = new FileReader(inputFile);
PEMParser pemParser = new PEMParser(fileReader);
FileOutputStream outputStream = new FileOutputStream(outputFile)) {
// Import PEM encoded PKCS#1 private key
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
KeyPair keyPair = converter.getKeyPair((PEMKeyPair)pemParser.readObject());
// Export DER encoded PKCS#8 private key
byte[] privateKey = keyPair.getPrivate().getEncoded();
outputStream.write(privateKey, 0, privateKey.length);
}

PKCS#1 and PKCS#8 format for RSA private key

PKCS#1 and PKCS#8 (Public-Key Cryptography Standard) are standards that govern the use of particular cryptographic primitives, padding, etc. Both define file formats that are used to store keys, certificates, and other relevant information.

PEM (Privacy-Enhanced Mail) and DER (Distinguished Encoding Rules) are a little bit more interesting. DER is the ASN.1 encoding for keys and certificates etc., which you'll be able to Google plenty about. Private keys and certificates are encoded using DER and can be saved directly like this. However, these files are binary and can't be copied and pasted easily, so many (if not most?) implementations accept PEM encoded files also. PEM is basically base64 encoded DER: we add a header, optional meta-data, and the base64 encoded DER data and we have a PEM file.



Related Topics



Leave a reply



Submit