不同系统中的通信处理以及电文信息传递

来源:互联网 发布:网络本科入学考试难吗 编辑:程序博客网 时间:2024/05/17 04:53

1,首先我们需要将要传递的信息做成电文形式

     一般有多种形态,一种是纯内容的按长度做成。

   1234567890|01234
      以上就是以长度做成的电文,前10个字节代表一个值,后6个字节代表一个值。

      一种就是按Map的键值对形式做成。如下所示:

   user=123456789   name=01234

2,由于安全性,我们需要对电文进行加密以及防止改窜的hash文

   

protected String authSSOPassword(HttpServletRequest request, String custom_pass)         throws ApplicationException {            // 用户的信息取得            UserInfo userInfo = (UserInfo) request.getSession().getAttribute(                    UserInfo.SESSION_KEY);            // 账号取得            String accountNum = userInfo.getAccount_num();            // 取得支行代码            String unitCd = userInfo.getUnit_cd();            // 验证密码            String ssoPassword = userInfo.getSso_password();                        Map map = new HashMap();                        // 设定暗号化参数            // 支行代码+账号            map.put("ac", unitCd + "-" + accountNum);               // 交易密码            map.put("ap", custom_pass);                         // 验证密码(DB的值复号化)            map.put("pw", ssoPassword);                        //通信的另外系统的URL            String url = "https://XXXX.XXXXX.XX/SsoAuth";            // 通信对方系统需要的Request的值设定            //String query = "_ControlID=c01&_PageID=p01&_DataStoreID=d01&_ActionID=a01";            String query = "_ControlID=AccSifControl&_DataStoreID=DSAccSifControl&_PageID=AccSifPwd00&_ActionID=chkTradePwd";                        //System.out.println("##########ac" + unitCd + "-" + accountNum);            //System.out.println("##########custom_pass" + custom_pass);            //System.out.println("##########ssoPassword" + ssoPassword);                        //https request送信【这个地方我前面文章有说明】            String res = SendReqestToFront.sendReq(url,query,map);                        //Response结果取得            int auth = SendHttpReq.isTradePass(res);                        //结果判断            if (auth == 1) {                return "errors.front.login.failure";            } else if (auth == 9) {                throw new KoSystemException("A3700001", null);            } else if (auth == 99) {                return "errors.front.login.maintain";            } else {                //成功            }        }                return null;    }


暗号化以及Hash化

public static String sendReq(String url, String query, Map inParams) throws ApplicationException {        try {            // 存放暗号化对象参数用的Instance生成            Map params = CipherUtil.createParametersMap();            Set set = inParams.keySet();                        Iterator it = set.iterator();            while(it.hasNext()){                String name = (String)it.next();                params.put(name,inParams.get(name));            }            /**              * 暗号化用的Key文名取得            */            String key = "SSO.key.file";            MessageResources settings = MessageResources                .getMessageResources("AplicationEnvironment");            String fileName = settings.getMessage(key);            //Key用容器对象            KeyContainer container = null;            try {                //取得暗号化Code                container = CipherUtil.getKeyContainer(fileName);            } catch (Exception e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            //从Key文件里生成キーファイルからキーコンテナを生成            if (container == null) {                container = CipherUtil.getKeyContainer(fileName);            }            // 生成防止改窜用的Hash串            final String hash = CipherUtil.createHash(container.getHASH_KEY(),                    params);            // 暗号化            final String encrypt = CipherUtil.encrypt(container.getAES_KEY(),                    container.getIv(), params);            query = query + "&hs=" + hash + "&value=" + encrypt;            //query = query + "&hash=" + hash + "&value=" + encrypt;System.out.println("##########url" + url);System.out.println("##########query" + query);            return SendHttpReq.sendHttps(url, query);        } catch (MalformedURLException e) {            throw new FrontConnectFailureException("", "A2700151", null);        } catch (IOException e) {            throw new FrontConnectFailureException("", "A2700152", null);        } catch (ClassNotFoundException e) {            throw new FrontConnectFailureException("", "A2700153", null);        } catch (InvalidKeyException e) {            throw new FrontConnectFailureException("", "A2700154", null);        } catch (NoSuchAlgorithmException e) {            throw new FrontConnectFailureException("", "A2700155", null);        } catch (NoSuchPaddingException e) {            throw new FrontConnectFailureException("", "A2700156", null);        } catch (InvalidAlgorithmParameterException e) {            throw new FrontConnectFailureException("", "A2700157", null);        }catch(Exception e){            throw new FrontConnectFailureException("", "A2700158", null);        }    }
以上加密最关键的是Key文件,那么做成Key文件也是要按照一定的规约来的。

package cn.co.dai.ags.common.crypt;import java.io.*;import java.security.*;/** * 暗号化/復号化Key作成类 * @version 1.0 2011/01/06 *  */public class KeyGenAp{//错误代码public static final int ERR_CD = 9;//随机数        private static final SecureRandom RANDOM = new SecureRandom();    /**     * 进行Key文件生成。     *      * @param file     */public static void makeKeyFile(String file){//AES共通鍵(256bit)的作成final byte[] AES_KEY = RANDOM.generateSeed(32);        System.out.println("AES_KEY : " + AES_KEY);// 暗号化用初期Head的生成        final String iv = CipherUtil.createInitialVector();        System.out.println("iv : " + iv);        //HASH Key的生成        final String HASH_KEY = "key";        //Key容器的生成KeyContainer container = new KeyContainer(AES_KEY,HASH_KEY,iv);ObjectOutputStream objStream = null;//做成的Key容器的内容出力到Key文件中try{objStream = new ObjectOutputStream(                                    new BufferedOutputStream(new FileOutputStream(file)));objStream.writeObject(container);}catch(IOException exIo){System.err.println("Key文件做成失败");System.err.println(exIo.getMessage());System.exit(ERR_CD);}finally{try{objStream.flush();objStream.close();}catch(Exception ex){ex.printStackTrace();System.exit(ERR_CD);}} }}
 * 此种方法生成的Key文件内容,好像会包含Key容器的信息,里面会含有key容器的全路径。 
 * 所以解密的时候这个Key容器的路径要和暗号化时候的一样。否则可能会复号化的时候会出现问题
关于
 * 此种方法生成的Key文件内容,好像会包含Key容器的信息,里面会含有key容器的全路径。 
 * 所以解密的时候这个Key容器的路径要和暗号化时候的一样。否则可能会复号化的时候会出现问题

这里类里面都使用的的CipherUtil.java文件是暗号化用的Util,使用了Java  Cryptographic Extension提供暗号化机能。

关于这个类有以下的说明。

*  * <pre> *     // AES共通鍵(128bit、192bit、256bit任何都可以) *     final byte[] AES_KEY = "12345678901234567890123456789012".getBytes(); *      *     // HASH共通鍵(任意) *     final String HASH_KEY = "hogehoge"; *      *     // 暗号化参数的生成 *     final Map params = CipherUtil.createParametersMap(); *     params.put("user_id", "m-takata"); *     params.put("access_id", "foo"); *     params.put("password", "fugafuga"); *     System.out.println("params : " + params); *      *     // 生成防止改窜用的Hash *     final String hash = CipherUtil.createHash(HASH_KEY, params); *     System.out.println("hash : " + hash); *      *     // 生成暗号化初期Head *     final String iv = CipherUtil.createInitialVector(); *     System.out.println("iv : " + iv); *      *     // 暗号化 *     final String encrypt = CipherUtil.encrypt(AES_KEY, iv, params); *     System.out.println("encrypt : " + encrypt); *      *     // 复号化(改窜check以及有效期check) *     final Map decrypt = CipherUtil.decrypt(AES_KEY, iv, encrypt, HASH_KEY, hash, 10000); *     System.out.println("decrypt : " + decrypt); * </pre> * 下面的例子<br> * <pre> *     params : {cn.co.dai.ags.crypt.CipherUtil.DATE=2004/09/23 01:16:23:176, user_id=m-takata, access_id=foo, password=fugafuga} *     hash : A88AB40FC28B209E4991C6FAE39B3160 *     iv : 03068117ABE8FF025E606DB773BD598F *     encrypt : A81D44F67E4E994D4F4DC4ED44E10C4F394520A596C81138093E1984D80FF25E1EE1EBCE8B83F130F6EBC0BC81B637582B05F3864025CEA430E42FB3D4FC4D7BEA0A2C1D77C99D89A5EFA795A6F8B9B42486FCCCC14AA994D3DF735E1D5986758922E07DFA74A43EDA1889DD0F1A0DFEE5FDC02F786156C2E868ACDEA8562353 *     decrypt : {cn.co.dai.ags.crypt.CipherUtil.DATE=2004/09/23 01:16:23:176, user_id=m-takata, access_id=foo, password=fugafuga} * </pre> * * @author M.Takata */

3,对方系统收到这个电文的时候,在解密

通过Request来得到我们放在URL后面的参数。

// 从Request中得到暗号化的文字列String encrypt = request.getParamter("value");// 从Request中取得Hash文字列String hash = request.getParamter("hs");// 暗号化Key容器取得 fileName=key文件的全路径(/wlasam07/user_projects/pldomain/application/pl/WEB-INF/classes/sso.keyKeyContainer container = CipherUtil.getKeyContainer(fileName);// 有效期long expires = 30000;// 复号化处理Map decrypt = CipherUtil.decrypt(container.getAES_KEY(),container.getIv(),encrypt,container.getHASH_KEY(),hash,expieres );//至此,把暗号化后的文字列都解密了。String aC = (String)decrypt.get("ac");
String aP = (String)decrypt.get("ap");
String pW = (String)decrypt.get("pw");
// 这样就取得了暗号化之前的前置系统传过来的用户账号,支行,密码等信息

相关类请参照:http://dl.dbank.com/c0rcpkmhlb

	
				
		
原创粉丝点击