问题
The original goal is:
Generate a https url where one of parameters is PKCS7 detached signature (RSA, SHA-256, UTF-8, BASE64).
What do I have:
- private key (.key file begin with "-----BEGIN RSA PRIVATE KEY-----", end like this "kIng0BFt5cjuur81oQqGJgvU+dC4vQio+hVc+eAQTGmNQJV56vAHcq4v -----END RSA PRIVATE KEY-----")
- self signed certificate (.cer file begin with "-----BEGIN CERTIFICATE-----", end like this "xwRtGsSkfOFL4ehKn/K7mgQEc1ZVPrxTC7C/g+7grbKufvqNmsYW4w== -----END CERTIFICATE-----")
- data to sign
I found a java code that do almost what I need.
Method signature:
public static String sign(PrivateKey privateKey,
X509Certificate certificate,
String data);
Now I'm stuck on how to get PrivateKey and X509Certficiate classes from given files.
I looked at many examples and got confused by these moments:
1.
KeyStore ks = KeyStore.getInstance("pkcs12");
or
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
Didn't find alternatives for PKCS7 standard.
A snippet of method that builds PrivateKey using bouncycastle library:
inputStream = Files.newInputStream(privateKeyFile.toPath()); reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); pemParser = new PEMParser(reader); PEMDecryptorProvider decryptorProvider = new JcePEMDecryptorProviderBuilder() .setProvider(PROVIDER) .build(privateKeyPassword.toCharArray()); PEMEncryptedKeyPair encryptedKeyPair = (PEMEncryptedKeyPair) pemParser.readObject(); PEMKeyPair keyPair = encryptedKeyPair.decryptKeyPair(decryptorProvider); ...
In this example I have to provide some privateKeyPassword to PEMDecryptorProvider. What is the point of this password and where can I get it?
From keyPair value I can get both privateKey and publicKey.
What is the connection between publicKey from PEMKeyPair and my certificate ? Are they the same?
Any help will be appreciated, thanks!
回答1:
You don't need bouncycastle to read in the public key as Java's CertificateFactory directly supports the format of your .cer file.
The private key appears to be in a PKCS1 format that openssl can produce. If you wish to keep that format this answer shows how to extract the private key. Combining the two, here is a short snippet to read in a certificate and a private key.
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import java.io.FileInputStream;
import java.io.FileReader;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
public class Main {
private static PrivateKey readPrivateKey(String filename) throws Exception {
PEMParser pemParser = new PEMParser(new FileReader(filename));
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
PEMKeyPair pemKeyPair = (PEMKeyPair) pemParser.readObject();
KeyPair kp = converter.getKeyPair(pemKeyPair);
return kp.getPrivate();
}
private static X509Certificate readCertificate(String filename) throws Exception {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
return (X509Certificate) certificateFactory.generateCertificate(new FileInputStream(filename));
}
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
PrivateKey privateKey = readPrivateKey("myKey.priv");
X509Certificate cert = readCertificate("mycert.cer");
}
}
来源:https://stackoverflow.com/questions/51812671/instantiate-java-security-classes-privatekey-and-x509certificate-from-key-and