I had some historical key material data in pkcs#1 format that needed to be in pkcs#8 for input into another system. Here's how to do it, using BouncyCastle:
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.DERObject;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import java.security.PrivateKey;
public static byte[] toPkcs8(PrivateKey k) throws IOException {
final String keyFormat = k.getFormat();
if (keyFormat.equals("PKCS#8")) {
return k.getEncoded();
}
else if (keyFormat.equals("PKCS#1")) {
try (ASN1InputStream asn1InputStream = new ASN1InputStream(k.getEncoded())) {
DERObject rsaPrivateKey = asn1InputStream.readObject();
return new PrivateKeyInfo(
new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption), rsaPrivateKey)
.getDEREncoded();
}
}
throw new IOException("Unexpected key format" + keyFormat);
}