JKS密码验证

下面的程序用来验证JKS的文件及密码是否正确

public static URL getStoreURL(String storePath) throws IOException
{
	URL url = null;
	// First see if this is a URL
	try
	{
		url = new URL(storePath);
	}
	catch (MalformedURLException e)
	{
		// Not a URL or a protocol without a handler so...
		// next try to locate this as file path
		File tst = new File(storePath);
		if (tst.exists() == true)
		{
			url = tst.toURL();
		} else
		{
			// not a file either, lastly try to locate this as a classpath
			// resource
			if (url == null)
			{
				ClassLoader loader = Thread.currentThread().getContextClassLoader();
				url = loader.getResource(storePath);
			}
		}
	}
	// Fail if no valid key store was located
	if (url == null)
	{
		String msg = "Failed to find url=" + storePath + " as a URL, file or resource";
		throw new MalformedURLException(msg);
	}
	return url;
}

public static KeyStore loadKeyStore(String storeType, URL storePathURL, String storePassword) throws Exception
{
	KeyStore keyStore = null;
	String provider = null;
	String providerName = null;

	if (provider != null)
	{
		keyStore = KeyStore.getInstance(storeType, provider);
	} else
		if (providerName != null)
		{
			keyStore = KeyStore.getInstance(storeType, providerName);
		} else
		{
			keyStore = KeyStore.getInstance(storeType);
		}
	if (storePathURL == null) { throw new Exception("Can not find store file for url because store url is null."); }
	// now that keystore instance created, need to load data from file
	InputStream keyStoreInputStream = null;
	try
	{
		keyStoreInputStream = storePathURL.openStream();
		// is ok for password to be null, as will just be used to check
		// integrity of store
		char[] password = storePassword != null ? storePassword.toCharArray() : null;
		keyStore.load(keyStoreInputStream, password);
	}
	finally
	{
		if (keyStoreInputStream != null)
		{
			try
			{
				keyStoreInputStream.close();
			}
			catch (IOException e)
			{
				// no op
			}
			keyStoreInputStream = null;
		}
	}
	return keyStore;
}

public static String verifyP12(String p12Path,String p12Pwd)
{
            String ret = "验证成功";
            try
            {
	URL ksURL = getStoreURL(p12Path);
                if(ksURL==null)throw new Exception(p12Path+"文件未找到");
                    
	loadKeyStore("PKCS12",ksURL,p12Pwd);
            }
            catch(Exception ex)
            {
                ret = ex.getMessage();
                ex.printStackTrace();
            }
            return ret;
}

public static String verifyJks(String jksPath,String jksPwd)
{
            String ret = "验证成功";
            try
            {
	URL ksURL = getStoreURL(jksPath);
	loadKeyStore("JKS",ksURL,jksPwd);
                
                if(ksURL==null)throw new Exception(jksPath+"文件未找到");
            }
            catch(Exception ex)
            {
                ret = ex.getMessage();
                ex.printStackTrace();
            }
            
            return ret;
}

AXIS2客户端支持TLS

只要设置下面几个环境变量就好啦;)

public static final String TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword";
public static final String TRUST_STORE = "javax.net.ssl.trustStore";
public static final String TRUST_STORE_TYPE = "javax.net.ssl.trustStoreType";
public static final String KEY_STORE_TYPE = "javax.net.ssl.keyStoreType";
public static final String KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword";
public static final String KEY_STORE = "javax.net.ssl.keyStore";

keytool生成key

生成keystore及cert

#生成私钥
keytool -genkey -validity 10000 -keyalg RSA -dname "CN=neohope OU=neohope O=neohope L=Shanghai C=CN" -keystore node1.jks -alias node1 -keypass password -storepass password 
#导出证书
keytool -export -file node1.crt -keystore node1.jks -alias node1 -keypass password -storepass password 
#生成truststore
keytool -import -trustcacerts -file node1.crt -keystore trust.jks -alias node1 -keypass password -storepass password 
#查看
keytool -list -keystore node1.jks
keytool -list -keystore trust.jks

jks转p12

keytool -importkeystore -srckeystore node1.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore node1.p12 -srcstorepass password -deststorepass password

JKS与P12证书互转

::JKS → P12
keytool -importkeystore -srckeystore keystore.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore keystore.p12

::P12 → JKS
keytool -importkeystore -srckeystore keystore.p12 -srcstoretype PKCS12 -deststoretype JKS -destkeystore keystore.jks

在这里,有一点大家一定要记住,P12的密码和JKS的密码一定要一致,否则很多容器(如Tomcat)无法加载。一般来说,JKS要求密码至少为6位,所以如果P12的密码位数太短,就要修改P12的密码啦:

openssl pkcs12 -in keystore.p12 -out keystore.pem -nodes
openssl pkcs12 -export -out keystore1.p12 -in keystore.pem

JBoss配置TLS

文件%JBOSS_HOME%\server\default\deploy\jboss-web.deployer\server.xml
增加下面陪孩子

<Connector port="8443" address="${jboss.bind.address}"
          protocol="HTTP/1.1" SSLEnabled="true" 
          maxThreads="100" strategy="ms" maxHttpHeaderSize="8192"
      	  emptySessionPath="true"
      	  scheme="https" secure="true" clientAuth="false" 
      	  disableUploadTimeout="true" 
      	  keystoreFile="${jboss.server.home.dir}/conf/node1.jks"
      	  keystorePass="passward"
      	  keyAlias="node1"
      	  sslProtocol = "TLS" />

Tomcat配置TLS

%TOMCAT_HOME%/conf/server.xml中添加以下配置即可

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
	       clientAuth="false" sslProtocol="TLS"
               keystoreFile="TOMCAT_HOME\conf\AXDS_2012_Keystore.jks"
               keystorePass="password"
	       truststoreFile="TOMCAT_HOME\conf\AXDS_2012_Truststore.jks" 
	       truststorePass="password"            
	       />

SpringAOP的两种代理方式

SpringAOP有两种代理方式:JDK动态代理和CGLIB。
如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理(该目标类型实现的所有接口都将被代理)。
如果被代理的目标对象没有实现任何接口,则会使用CGLIB代理。

所以,当你将一个JDK动态代理的对象Cast为一个Class而不是Interface的时候,就会报ClassCastException

这时,就要强制使用CGLIB代理

<aop:config proxy-target-class="true">
...
</aop:config>

或在使用@AspectJ时强制使用CGLIB代理

<aop:aspectj-autoproxy proxy-target-class="true">
    <aop:include name="bean1" />
    <aop:include name="bean2" />
    ....
</aop:aspectj-autoproxy>

Java多线程同步的几种方式

1、原子变量
AtomicBoolean
AtomicInteger
AtomicLong
AtomicReference
AtomicStampedReference
AtomicIntegerArray
AtomicLongArray
AtomicReferenceArray

2、Unsafe类
Unsafe.monitorEnter(this);
Unsafe.monitorExit(this);

3、synchronized关键字
同步静态方法
同步普通方法
同步代码块

4、锁
Object.wait()方法和Object.notify()方法:

5、ReentrantLock重入锁
Condition

6、ReadWriteLock读写锁
StampedLock

7、Semaphore信号量

8、BlockingQueue阻塞队列
ArrayBlockingQueue
LinkedBlockingQueue
PriorityBlockingQueue
LinkedBlockingDeque
SynchronousQueue
DelayQueue

9、CyclicBarrier

10、CountDownLatch

11、Phaser

12、Exchanger

13、ForkJoinPool
RecursiveTask

13、Future
CompletionService
CompletableFuture
FutureTask

14、Collections
Collections.synchronizedList
Collections.synchronizedSet
Collections.synchronizedMap

15、volatile变量
可以解决并发读的问题,无法单独解决并发写的问题

Java多线程实现的几种方式

1、继承Thread类

2、实现Runnable接口

3、实现Callable接口+Future封装

4、定时器

5、使用Executors提供的ExecutorService
Executors.newCachedThreadPool
Executors.newFixedThreadPool
Executors.newScheduledThreadPool
Executors.newSingleThreadExecutor
Executors.newWorkStealingPool

6、自定义ThreadPoolExecutor+ThreadFactory

7、parallelStream

8、Fork Join
ForkJoinPool
RecursiveTask
RecursiveAction

9、调用本地方法
使用JNI等