JVM证书导入: 通过java代码导入证书

JVM导入证书

传统都是通过java命令导入证书,但是比较繁琐,对于sso-cas系统部署证书也是一件烦心事。遂有了如下代码。

核心代码

import java.io.*;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

/**
 * @author wangqimeng
 * @date 2019/10/15 13:36
 */
@Slf4j
public class KeyStoreUtil {

    private KeyStoreUtil() {

    }

    public static void saveCertificate(String cerNameAlias,
                                       InputStream certIn,
                                       String passphrase) throws Exception {
        log.debug("程序进行证书导入工作");
        final char sep = File.separatorChar;
        File dir = new File(System.getProperty("java.home") + sep + "lib" + sep + "security");
        log.debug("导入证书路径:{}", dir);
        char[] passphraseArray = passphrase.toCharArray();
        OutputStream out = null;
        File targetKeyStore = new File(dir, "cacerts");
        //输入流和输出流不可同时在同一文件,否则文件会被置空
        try (InputStream localCertIn = new FileInputStream(targetKeyStore)) {

            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
            keystore.load(localCertIn, passphraseArray);
            //判断是否已经存在在该证书
            if (keystore.containsAlias(cerNameAlias)) {
                log.debug("已经存在该证书:{}", cerNameAlias);
                return;
            }
            BufferedInputStream bis = new BufferedInputStream(certIn);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            while (bis.available() > 0) {
                Certificate cert = cf.generateCertificate(bis);
                keystore.setCertificateEntry(cerNameAlias, cert);
            }
            out = new FileOutputStream(targetKeyStore);
            keystore.store(out, passphraseArray);
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    log.error("输出流关闭失败");
                }
            }
        }
    }

    public static void doKeyStore(ResourceLoader resourceLoader,
                                  String[] certificatePath, String certificateFileName,
                                  String certificateNameAlias, String passphrase) throws Exception {
        try (InputStream inputStream = getResource(resourceLoader, certificatePath, certificateFileName).getInputStream()) {
            KeyStoreUtil.saveCertificate(certificateNameAlias,
                    inputStream, passphrase);
        }
    }

    private static Resource getResource(ResourceLoader resourceLoader, String[] certificatePath, String fileName) {
        for (int i = certificatePath.length - 1; i >= 0; i--) {
            Resource resource = resourceLoader.getResource(certificatePath[i] + fileName);
            if (resource.exists()) {
                return resource;
            }
        }
        throw new RuntimeException(fileName + "资源未找到");
    }
}

Test

import org.junit.Before;
import org.junit.Test;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;

/**
 * @author wangqimeng
 * @date 2019/10/28 11:36
 */
public class KeyStoreUtilTest {

    private ResourceLoader resourceLoader;

    private String[] certificatePath;

    private String certificateFileName;

    private String certificateNameAlias;

    private String passphrase;

    @Before
    public void init() {
        this.resourceLoader = new DefaultResourceLoader();
        this.certificatePath = new String[]{"classpath:/ssl/", "file:./ssl/"};
        this.certificateFileName = "sso.ga.cer";
        this.certificateNameAlias = "sso.ga.cer";
        this.passphrase = "changeit";
    }

    @Test
    public void doKeyStore() throws Exception {
        KeyStoreUtil.doKeyStore(resourceLoader,
                certificatePath,certificateFileName,
                certificateNameAlias,passphrase);
    }
}

For Spring Boot

证书实体


import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

/**
 * @author wangqimeng
 * @date 2019/10/15 11:06
 */
@Data
@Validated
@ConfigurationProperties(prefix = "sso")
public class CertificateProperties {

    private String certificatePath;

    private String certificateNameAlias;

    private String passphrase = "changeit";

    private boolean autoImportCertificate;

}

example

sso:
  auto-import-certificate: true
  certificate-name-alias: sso.ga.cer
  certificate-path: public/ssl/sso.ga.cer
  passphrase: changeit

Runner

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.io.ResourceLoader;

/**
 * @author wangqimeng
 * @date 2019/10/15 11:15
 */
@Slf4j
public class AutoImportRunner implements ApplicationRunner {

    @Autowired
    private CertificateProperties certificateProperties;

    @Autowired
    private ResourceLoader resourceLoader;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        KeyStoreUtil.doKeyStore(resourceLoader, certificateProperties.getCertificatePath(), certificateProperties.getCertificateFileName(),
                certificateProperties.getCertificateNameAlias(), certificateProperties.getPassphrase());
    }

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值