前一阵遇到一个需求,要求做一个单点登录,虽然单点登录不难但是,由于对方的api比较老旧只能采用java_api 获取的方式才能获取 用户信息流程大概如下:
点击第三方登录 java_api获取登录地址并跳转 输入账号密码 登陆后返回中间件
本商城 -------------------------> java中间件 ----------------------------------------->第三方登录
| java_api 获取信息并加密 | 跳转回java中间件 |
|<----------------------------------|<--------------------------------------------------|
将加密后的信息放入链接跳转回商城
虽然过程比较曲折但是登录以后还是跳转回来了,问题出在由于是java中间件获取了用户的信息,带入连接中如果是普通的base64 编码等于是完全的暴露了出来,所以采用了DES--CBC 双边对称加密(由于链接时效设定为只有一分钟,所以避免了理论上的被破解可能)
java 的加密方法
String curUserName = "";
String attr = "cn";
String Name = "";
String[] values = im.getUserAttribute( curUser, attr);
for (int i=0; i< values.length; i++)
{
curUserName = values[0];
}
java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// key
String key = "xxxxxxxx"
java.util.Date currentTime = new java.util.Date();
String str_date1 = formatter.format(currentTime);
// 加密
String user_name_encode = DESEncryptTools.EncryptDES(curUserName, key);
String user_id_encode = DESEncryptTools.EncryptDES(curUser, key);
String data_encode = DESEncryptTools.EncryptDES(str_date1, key);
String user_name_url = java.net.URLEncoder.encode(user_name_encode);
String user_id_url = java.net.URLEncoder.encode(user_id_encode);
String data_url = java.net.URLEncoder.encode(data_encode);
将参数加密然后放在url当中传输
def get_encode_user
# 秘钥 保持和加密方相同
key = 'xxxxxxxx'
# 利用秘钥解密
user_id = decrypt(params[:user_id], key) rescue nil
user_name = decrypt(params[:user_name], key) rescue nil
data = DateTime.parse(decrypt(params[:data], key)) rescue nil
if data <= DateTime.now - 1.minute
return render :html => '链接已失效,请重新登录'
end
email = user_id + "@sinopr.com"
user = AncientBackend::User.find_or_initialize_by(email: email, login_name: user_name, real_name: user_name)
user.password = SecureRandom.hex if user.password.blank?
user.company_id = @personality.center.purchasers.is_personal.first.id
user.save
user.add_role(2) if user.roles.blank?
sign_in(user)
redirect_to :root
end
对应的的解密方法
# DES-CBC 解密
def decrypt(str, key)
encrypted_string = Base64.decode64(str)
cipher = OpenSSL::Cipher::DES.new("CBC")
cipher.decrypt
cipher.key = key
result = cipher.update(encrypted_string) + cipher.final
end
java 加密的方法写好后要打包成jar包引入后才能使用 - - !
对应的ruby 加密方式还有其他的暂且不表