前言
关于单点登录(SSO)网上也有很多帖子,但是以我个人的角度来看,大多都是一知半解,看完一圈也还是懵的,而且基本上都是理念,实实在在的去实践的基本上没有,而且内容基本上就是一模一样,这篇文章给大家也是提供一个单点登录的解决方案,至少看完和实践完之后,你知道大概怎么去实现,我这种实现方案也只适用于两个服务之间的通信登录,但是我认为哪有那么多的大型服务通信,又不是人人项目皆淘宝
非对称性加密,双向加密(RSA+AES)
本文我们用到了一种构思,在不传递密钥的情况下,完成解密,这被称为"Diffie-Hellman密钥交换算法",也正是因为这个算法的产生,人类终于可以实现非对称加密了,举个例子:
1.B要先生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。
2.A获取B的公钥,然后用它对信息加密。
3.B得到加密后的信息,用私钥解密。
理论上如果公钥加密的信息只有私钥解得开,那么只要私钥不泄漏,通信就是安全的。
觉得文字不理解的,我提供了一个流程图:
本文单点登录就是基于这个流程实现,下面我们来实操非对称性加密,上代码:
AES加密工具类:
public class AESUtil {
//生成AES秘钥,然后Base64编码
public static String genKeyAES() throws Exception{
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
SecretKey key = keyGen.generateKey();
String base64Str = byte2Base64(key.getEncoded());
return base64Str;
}
//将Base64编码后的AES秘钥转换成SecretKey对象
public static SecretKey loadKeyAES(String base64Key) throws Exception{
byte[] bytes = base642Byte(base64Key);
SecretKeySpec key = new SecretKeySpec(bytes, "AES");
return key;
}
//加密
public static byte[] encryptAES(byte[] source, SecretKey key) throws Exception{
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(source);
}
//解密
public static byte[] decryptAES(byte[] source, SecretKey key) throws Exception{
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(source);
}
//字节数组转Base64编码
public static String byte2Base64(byte[] bytes){
BASE64Encoder encoder = new BASE64Encoder();
return encoder.en