带 spring 靴子的充气城堡
Bouncy castle with spring boot
我正在尝试通过 http 使用 Https,我使用 bouncy castle 生成了 CA 证书,并从 .cer
文件生成了 jks
文件,spring 引导成功启动随嵌入式 tomcat.
提供的属性
问题是当我添加使用另一个配置 class.
以编程方式信任存储
这是我的代码:
import org.apache.commons.codec.binary.Base64; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cmp.CertRepMessage; import org.bouncycastle.asn1.cmp.PKIBody; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.CertException; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.cmp.CMPException; import org.bouncycastle.cert.cmp.ProtectedPKIMessage; import org.bouncycastle.cert.cmp.ProtectedPKIMessageBuilder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.security.*; import java.security.cert.X509Certificate; import java.util.Date;
public class generateService {
private static final String BC = BouncyCastleProvider.PROVIDER_NAME;
private static X509CertificateHolder makeV3Certificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN)
throws GeneralSecurityException, IOException, OperatorCreationException, CertException
{
PublicKey subPub = subKP.getPublic();
PrivateKey issPriv = issKP.getPrivate();
PublicKey issPub = issKP.getPublic();
X509v3CertificateBuilder v1CertGen = new JcaX509v3CertificateBuilder(
new X500Name(_issDN),
BigInteger.valueOf(System.currentTimeMillis()),
new Date(System.currentTimeMillis()),
new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)),
new X500Name(_subDN),
subPub);
ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA").setProvider(BC).build(issPriv);
X509CertificateHolder certHolder = v1CertGen.build(signer);
ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider(BC).build(issPub);
return certHolder;
}
public X509Certificate test(KeyPair kp) throws OperatorCreationException, GeneralSecurityException, CertException, IOException, CMPException {
Provider bcProvider = new BouncyCastleProvider();
Security.addProvider(bcProvider);
X509CertificateHolder cert = makeV3Certificate(kp, "CN=CA", kp, "CN=CA");
GeneralName sender = new GeneralName(new X500Name("CN=CA"));
GeneralName recipient = new GeneralName(new X500Name("CN=CA"));
ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(kp.getPrivate());
ProtectedPKIMessage message = new ProtectedPKIMessageBuilder(sender, recipient)
.setBody(new PKIBody(PKIBody.TYPE_INIT_REP, CertRepMessage.getInstance(new DERSequence(new DERSequence()))))
.addCMPCertificate(cert)
.build(signer);
X509Certificate jcaCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(message.getCertificates()[0]);
return jcaCert;
}
public void generateJKS() throws GeneralSecurityException, IOException, OperatorCreationException, CMPException, CertException {
Provider bcProvider = new BouncyCastleProvider();
Security.addProvider(bcProvider);
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
X509Certificate certificate = test(keyPair);
final FileOutputStream os = new FileOutputStream("E:\cert4.cer");
os.write("-----BEGIN CERTIFICATE-----\n".getBytes("US-ASCII"));
os.write(Base64.encodeBase64(certificate.getEncoded(), true));
os.write("-----END CERTIFICATE-----\n".getBytes("US-ASCII"));
os.close();
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null,null);
X509Certificate[] certChain = new X509Certificate[1];
certChain[0] = certificate;
keyStore.setKeyEntry("myaliaskey", (Key)keyPair.getPrivate(), "secret".toCharArray(), certChain);
OutputStream outputStream = new FileOutputStream("E:\keystoreRSA4.jks");
keyStore.store(outputStream, "secret".toCharArray());
outputStream.flush();
outputStream.close();
}
public static void main(String[] args) throws Exception {
new generateService().generateJKS();
} }
Application.properties:
server.port = 8443 server.http.port = 8080 server.ssl.key-store = E:\keystoreRSA4.jks server.ssl.key-password = secret server.ssl.keyAlias = myaliaskey
/******************************************** *******************************/
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Configuration public class SSLConfig {
@PostConstruct
private void configureSSL() {
System.setProperty("https.protocols", "TLSv1.2");
System.setProperty("javax.net.ssl.trustStore", "E:\keystoreRSA4.jks");
System.setProperty("javax.net.ssl.keyStore", "E:\keystoreRSA4.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "secret");
} }
import org.apache.catalina.Context; import org.apache.catalina.connector.Connector; import org.apache.tomcat.util.descriptor.web.SecurityCollection; import org.apache.tomcat.util.descriptor.web.SecurityConstraint; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
@Configuration public class TomcatConfig {
@Value("${server.http.port}")
private int httpPort;
@Value("${server.port}")
private int httpsPort;
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(initiateHttpConnector());
return tomcat;
}
public Connector initiateHttpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("https");
connector.setPort(httpPort);
connector.setSecure(true);
connector.setRedirectPort(httpsPort);
return connector;
} }
如有任何帮助,我们将不胜感激,并提前致谢。
how i can figure it to let the browser accept it as trust certificate?
幸运的是,你不能。有关于话题的讨论 in this question:
If we simply said "HTTPS is now possible with self-signed certificates", your browser could not distinguish whether a site you are trying to visit has a self-signed cert because it is supposed to, or because you are being attacked. Thus, it would decrease security.
您必须在浏览器中添加例外才能接受您的证书。通常在开发期间。对于生产用途,您必须从 Verisign.
等受信任的供应商处购买证书
要向您的浏览器添加例外,请参阅this other question。
干杯!
我正在尝试通过 http 使用 Https,我使用 bouncy castle 生成了 CA 证书,并从 .cer
文件生成了 jks
文件,spring 引导成功启动随嵌入式 tomcat.
问题是当我添加使用另一个配置 class.
以编程方式信任存储这是我的代码:
import org.apache.commons.codec.binary.Base64; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cmp.CertRepMessage; import org.bouncycastle.asn1.cmp.PKIBody; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.CertException; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.cmp.CMPException; import org.bouncycastle.cert.cmp.ProtectedPKIMessage; import org.bouncycastle.cert.cmp.ProtectedPKIMessageBuilder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.security.*; import java.security.cert.X509Certificate; import java.util.Date;
public class generateService {
private static final String BC = BouncyCastleProvider.PROVIDER_NAME;
private static X509CertificateHolder makeV3Certificate(KeyPair subKP, String _subDN, KeyPair issKP, String _issDN)
throws GeneralSecurityException, IOException, OperatorCreationException, CertException
{
PublicKey subPub = subKP.getPublic();
PrivateKey issPriv = issKP.getPrivate();
PublicKey issPub = issKP.getPublic();
X509v3CertificateBuilder v1CertGen = new JcaX509v3CertificateBuilder(
new X500Name(_issDN),
BigInteger.valueOf(System.currentTimeMillis()),
new Date(System.currentTimeMillis()),
new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)),
new X500Name(_subDN),
subPub);
ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA").setProvider(BC).build(issPriv);
X509CertificateHolder certHolder = v1CertGen.build(signer);
ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider(BC).build(issPub);
return certHolder;
}
public X509Certificate test(KeyPair kp) throws OperatorCreationException, GeneralSecurityException, CertException, IOException, CMPException {
Provider bcProvider = new BouncyCastleProvider();
Security.addProvider(bcProvider);
X509CertificateHolder cert = makeV3Certificate(kp, "CN=CA", kp, "CN=CA");
GeneralName sender = new GeneralName(new X500Name("CN=CA"));
GeneralName recipient = new GeneralName(new X500Name("CN=CA"));
ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(kp.getPrivate());
ProtectedPKIMessage message = new ProtectedPKIMessageBuilder(sender, recipient)
.setBody(new PKIBody(PKIBody.TYPE_INIT_REP, CertRepMessage.getInstance(new DERSequence(new DERSequence()))))
.addCMPCertificate(cert)
.build(signer);
X509Certificate jcaCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(message.getCertificates()[0]);
return jcaCert;
}
public void generateJKS() throws GeneralSecurityException, IOException, OperatorCreationException, CMPException, CertException {
Provider bcProvider = new BouncyCastleProvider();
Security.addProvider(bcProvider);
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
X509Certificate certificate = test(keyPair);
final FileOutputStream os = new FileOutputStream("E:\cert4.cer");
os.write("-----BEGIN CERTIFICATE-----\n".getBytes("US-ASCII"));
os.write(Base64.encodeBase64(certificate.getEncoded(), true));
os.write("-----END CERTIFICATE-----\n".getBytes("US-ASCII"));
os.close();
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null,null);
X509Certificate[] certChain = new X509Certificate[1];
certChain[0] = certificate;
keyStore.setKeyEntry("myaliaskey", (Key)keyPair.getPrivate(), "secret".toCharArray(), certChain);
OutputStream outputStream = new FileOutputStream("E:\keystoreRSA4.jks");
keyStore.store(outputStream, "secret".toCharArray());
outputStream.flush();
outputStream.close();
}
public static void main(String[] args) throws Exception {
new generateService().generateJKS();
} }
Application.properties:
server.port = 8443 server.http.port = 8080 server.ssl.key-store = E:\keystoreRSA4.jks server.ssl.key-password = secret server.ssl.keyAlias = myaliaskey
/******************************************** *******************************/
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Configuration public class SSLConfig {
@PostConstruct
private void configureSSL() {
System.setProperty("https.protocols", "TLSv1.2");
System.setProperty("javax.net.ssl.trustStore", "E:\keystoreRSA4.jks");
System.setProperty("javax.net.ssl.keyStore", "E:\keystoreRSA4.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "secret");
} }
import org.apache.catalina.Context; import org.apache.catalina.connector.Connector; import org.apache.tomcat.util.descriptor.web.SecurityCollection; import org.apache.tomcat.util.descriptor.web.SecurityConstraint; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
@Configuration public class TomcatConfig {
@Value("${server.http.port}")
private int httpPort;
@Value("${server.port}")
private int httpsPort;
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(initiateHttpConnector());
return tomcat;
}
public Connector initiateHttpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("https");
connector.setPort(httpPort);
connector.setSecure(true);
connector.setRedirectPort(httpsPort);
return connector;
} }
如有任何帮助,我们将不胜感激,并提前致谢。
how i can figure it to let the browser accept it as trust certificate?
幸运的是,你不能。有关于话题的讨论 in this question:
If we simply said "HTTPS is now possible with self-signed certificates", your browser could not distinguish whether a site you are trying to visit has a self-signed cert because it is supposed to, or because you are being attacked. Thus, it would decrease security.
您必须在浏览器中添加例外才能接受您的证书。通常在开发期间。对于生产用途,您必须从 Verisign.
等受信任的供应商处购买证书要向您的浏览器添加例外,请参阅this other question。
干杯!