联通彩e接口开发

Posted on 2005-09-08 13:56  齐国老兵  阅读(1064)  评论(2编辑  收藏
前段时间开发联通彩e接口,期间遇到很多问题,在朋友的帮助和自己的摸索中总算完成了接口的开发。 在sp联盟论坛上也见到许多同行各种各样的问题,因此将开发细节整理成文,希望能给与我当初一样 困扰的人以帮助。 第一次接触彩e,感觉有点无从下手,接口指南几百页之多,我在开发的时候不知道联通提供测试的接入 平台以供调试,而是对着接口规范编写代码,然后模拟接口规则生成数据,这些都是在单元测试中完成 的,到接入uni-wise测试环境时,问题多多。

概述
本文以java语言为例,讲述彩e接口开发的点滴。参考的接口指南为《中国联通增值业务综合管理及接入平台SP接口规范v1.2》, 文中代码均经过测试,且与uni-wise平台能正常运行。彩e与sp接口包括:sso接口、预定接口、取消接口、彩e push接口,取 消push接口,查询push接口、wap push接口。文中除了wap push接口,其余的将会一一介绍。 彩e接口的开发其实就是sp与联通uni-wise平台之间的通信,uni-wise平台是以web方式工作,因此与sp的交互大部分通 过http+xml协议传输。 笔者在开发的过程中也曾用C#写过彩e的部分接口代码,如有此需求,我也将整理成文。

SSO 是 Single sign on的缩写,即单点登录,彩e接口中实现的功能是,用户在uni-wise平台或sp平台只需登录一次,即可 访问相关资源。通过cookies机制实现。

1.1. 传输安全
出于安全考虑,网络的传输中经常对传输数据做加密和编码处理,彩e接口开发中的一个关键点也是对加密解密的代码编写。 其中涉及以下几种:

1、md5加密,该加密算法是单向加密,即加密的数据不能再通过解密还原。相关类包含在java.security.MessageDigest包中。

2、3-DES加密,该加密算法是可逆的,解密方可以通过与加密方约定的密钥匙进行解密。相关类包含在javax.crypto.*包中。

3、base64编码,是用于传输8bit字节代码最常用的编码方式。相关类在sun.misc.BASE64Decoder 和sun.misc.BASE64Encoder 中。

4、URLEncoder编码,是一种字符编码,保证被传送的参数由遵循规范的文本组成。相关类在java.net.URLEncoder包中。

1.2. 生成请求票根

当用户从SP平台向uni-wise发起登录请求时,SP平台需要生成一个合法的票根,以http协议传输给uni-wise平台。 生成请求票根的规则是:SPTicketRequestValue = URLEncoding{UNICODE(SPCode +“$”)+ Base64 [Encrypt (UNICODE(Seed + “$”)+ Digest)]}

1、生成Seed: returnUrl + "$" + timeStamp;returnUrl为登录成功后接收uni-wise的响应票根链接。timeStamp为生成的 时间戳。

例 1.1. TimeStamp实现代码

public String getTimeStamp()
{
Calendar cal=Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
String timeStamp=formatter.format(cal.getTime());
return timeStamp;
}

2、生成Digest :Base64{Hash[UNICODE(SPCode +"$"+ Seed + "$" + SPKey)]},其中Hash算法采用md5

例 1.2. Digest的实现代码

public String getDigest(String strSrc)
{
//String strSrc = spCode + "$" + getSeed() + "$" + spKey;
BASE64Encoder base64en = new BASE64Encoder();
String digest="";
try
{
byte[] srcMD5 = md5Encrypt(strSrc);
digest = base64en.encode(srcMD5); (1)
}
catch(Exception e){
e.printStackTrace();
}
return digest;
}

private byte[] md5Encrypt(String strSrc)
{
byte[] returnByte = null;
try
{
MessageDigest md5 = MessageDigest.getInstance("MD5"); (2)
returnByte = md5.digest(strSrc.getBytes("GBK"));
}
catch(Exception e)
{
e.printStackTrace();
}
return returnByte;
}

(1) 调用3-DES的加密函数。

(2) base64编码3-DES的数据时,得到的字符串有换行符号,一定要去掉,否则uni-wise平台解析票根不会成功, 提示“sp验证失败”。在开发的过程中,因为这个问题让我束手无策,一个朋友告诉我可以问联通要一段加密后 的文字,然后去和自己生成的字符串比较,这是个不错的调试方法。我最后比较发现我生成的字符串唯一不同的 是多了换行。我用c#语言也写了票根请求程序,没有发现这个问题。

(3) 从原始密匙数据创建DESedeKeySpec对象。

(4) 创建一个密匙工厂,然后用它把DESKeySpec转换成一个SecretKey对象。

(5) 根据密匙工厂,得到一个密钥匙实例。

(6) 创建Cipher对象。

(7) 初始化Cipher对象(带入密钥匙)。

(8) 执行加密操作。

为方便调试给出一段加密后的字符串(用自己的代码加密同样的字符串后得到的结果和给出的结果进行比较)

content = key = 1234;
result = base64(3des(contentbyte,keybyte));
result : "25Pxmw/+/qKg2arQpLdvqQ=="

1.3. 解析响应票根
uni-wise平台收到请求票根后会进行解析票根,然后用户登录后uni-wise又会将登录信息放在响应票根中,传回给请求票根者。 (传回的地址是请求票根中的”returnUrl“)。传输的协议也是http+xml.

1、UrlEncoding的解码(笔者在测试中发现在uni-wise测试平台首先需要对所得的票根响应串进行urlEncoding解码,这也是接口 遵照接口手册进行的,但是在uni-wise正式平台下得到的响应票根已经是对urlEncoding解码的)。

import java.net.URLDecoder;
URLDecoder.decode(strEncoding);

2、分割响应票根,得到加密的字符串。分割很简单,以"$"为分割符,得到"$"后面的字符串即可。

3、对加密字符串进行base64解码。

import sun.misc.BASE64Decoder;
BASE64Decoder base64Decode = new BASE64Decoder();
base64Decode.decodeBuffer(strEnBase64);

4、对base64解码的值进行3-DES解密(密钥匙等同于加密的密钥匙)。

public String deCrypt(byte[] debase64)
{
String strDe = null;
Cipher cipher = null;
try
{
cipher=Cipher.getInstance("DESede");
byte[] key = getEnKey(spKey); (1)
DESedeKeySpec dks = new DESedeKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey sKey = keyFactory.generateSecret(dks);
cipher.init(Cipher.DECRYPT_MODE, sKey); (2)
byte ciphertext[] = cipher.doFinal(debase64);
strDe = new String(ciphertext,"UTF-16LE");
}
catch(Exception ex)
{
strDe = "";
ex.printStackTrace();
}
return strDe;
}

Copyright © 2021 齐国老兵
Powered by .NET 5.0 on Kubernetes