package com.nuvole.hnnx.hnnxPay; import org.springframework.core.io.ClassPathResource; import org.springframework.util.Assert; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.security.Key; import java.security.KeyStore; import java.security.cert.Certificate; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; /** * @author awlwen * @since 2017/11/30 */ public class KeyProviderImpl implements KeyProvider { private static final Map SUPPORTED_KEY_TYPE = new HashMap(); static { SUPPORTED_KEY_TYPE.put("ks", "jks"); SUPPORTED_KEY_TYPE.put("jks", "jks"); SUPPORTED_KEY_TYPE.put("pfx", "pkcs12"); SUPPORTED_KEY_TYPE.put("p12", "pkcs12"); } /** * 密钥容器文件路径 */ private String file; /** * 密钥容器密码 */ private String password; /** * 密钥容器 */ private KeyStore keystore; /** * 初始化标志 */ private boolean initialized = false; /** * 构造器 * * @param file 密钥容器文件路径 * @param password 密钥容器密码 */ public KeyProviderImpl(String file, String password) { super(); Assert.notNull(file, "file is required; it must not be null"); init(file, password); } /** * 根据文件扩展名获取密钥容器类型 * * @param file * @return */ private String resolveType(String file) { Assert.notNull(file, "file is required; it must not be null"); String suffix = file.substring(file.lastIndexOf(".") + 1); Assert.notNull(suffix, "suffix could not be resolved"); String supportedType = SUPPORTED_KEY_TYPE.get(suffix.toLowerCase()); Assert.notNull(supportedType, "unsupported key type"); return supportedType; } /** * 初始化,加载密钥容器 * * @param file 密钥容器文件路径 * @param password 密钥容器密码 */ private void init(String file, String password) { InputStream is = null; try { //建立文件输入流读取密钥容器 if (file.startsWith("classpath:")) { is = new ClassPathResource(file.replace("classpath:", "")).getInputStream(); } else { is = new BufferedInputStream(new FileInputStream(file)); } //根据文件扩展名建立相应的密钥容器类型 keystore = KeyStore.getInstance(resolveType(file)); //将密钥容器密码转换为char数组 char[] pwd = password == null ? null : password.toCharArray(); //从指定的输入流中加载密钥容器 keystore.load(is, pwd); initialized = true; } catch (Exception ex) { throw new RuntimeException(ex); } finally { if (is != null) { try { is.close(); } catch (IOException ex) { throw new RuntimeException(ex); } } } } /* (non-Javadoc) * @see com.csii.sg.security.KeyProvider#getKey(java.lang.String, java.lang.String) */ public Key getKey(String id, String password) { Assert.isTrue(initialized, "keyProvider not been initialized"); try { if (id == null) { Enumeration aliases = keystore.aliases(); for (int count = 0; aliases.hasMoreElements(); count++) { if (count > 1) { throw new IllegalArgumentException("key id not specified"); } String alias = aliases.nextElement(); if (keystore.isKeyEntry(alias)) { id = alias; } } } char[] pwd = password == null ? null : password.toCharArray(); return keystore.getKey(id, pwd); } catch (Exception ex) { throw new RuntimeException(ex); } } /* (non-Javadoc) * @see com.csii.sg.security.KeyProvider#getCertificate(java.lang.String) */ public Certificate getCertificate(String id) { Assert.isTrue(initialized, "keyProvider not been initialized"); try { return keystore.getCertificate(id); } catch (Exception ex) { throw new RuntimeException(ex); } } /* (non-Javadoc) * @see com.csii.sg.security.KeyProvider#getCertificateChain(java.lang.String) */ public Certificate[] getCertificateChain(String id) { Assert.isTrue(initialized, "keyProvider not been initialized"); try { return keystore.getCertificateChain(id); } catch (Exception ex) { throw new RuntimeException(ex); } } /** * @param file the file to set */ public void setFile(String file) { this.file = file; } /** * @param password the password to set */ public void setPassword(String password) { this.password = password; } }