首页 文章

与 Spring 天起动的有弹性的城堡

提问于
浏览
1

我正在尝试使用Https over http,我使用bouncy castle生成CA证书并从 .cer 文件生成 jks 文件,Spring启动成功启动了嵌入式tomcat提供的属性 .

问题是我从浏览器总是 insecure ssl certificate (例如从chrome: This CA Root certificate is not trusted because it is not in the Trusted Root Certification Authorities store. ),而我用另一个配置类以编程方式添加信任库 .

这是我的代码:

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;
    } }

任何帮助将不胜感激,并提前感谢您 .

1 回答

  • 1

    我怎么能让它让浏览器接受它作为信任证书?

    幸运的是,您可以't. There'讨论主题in this question

    如果我们只是简单地说“现在可以使用自签名证书进行HTTPS”,则您的浏览器无法区分您尝试访问的站点是否具有自签名证书,因为它应该是,或者因为您受到攻击 . 因此,它会降低安全性 .

    您必须在浏览器中添加例外以接受您的证书 . 通常在开发期间 . 对于 生产环境 用途,您必须从可信赖的供应商处购买证书,例如Verisign .

    要在浏览器中添加例外,请参阅this other question .

    干杯!

相关问题