IC卡应用系统开发-(二)加密机访问

<script type="text/javascript"> google_ad_client = "pub-8800625213955058"; /* 336x280, 创建于 07-11-21 */ google_ad_slot = "0989131976"; google_ad_width = 336; google_ad_height = 280; // </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script> 在有卡片的应用系统中,很多数据都是进行加密处理的.如有的系统是采用密文传输数据,有的采用明文 MAC方式,也有的是密文 MAC.但不管采用那种方式,都是与加密/解密息息相关的. 在我开发的系统中,为保证系统的安全,卡片有效和数据完整,做了一个软加密机.就是一个java程序实现对数据的加密,解密和MAC运算.采用3DES算法,它提供密钥经分散后的加/解功能.关于java实现DES的程序,在网上可以找到,这里不在赘述.本文介绍对软加密机访问的例程. 我还是定义了3个类: 接口类:IHSM.JAVA,说明对外提供的行为. 实现类:HSM.JAVA,对加密机的访问具体实现. 异常类:HSMException.java,继承系统Exception类. package com.microapp.business.hsm; /** *

Title: System

* *

Description:

* *

Copyright: Copyright (c) 2005

* *

Company: my

* * @author microapp * @version 1.0 */ public interface IHSM { /** * 加密数据 * @param interspersed * @param data String * @param index int * @return String * @throws HSMException */ public String getEncryption(String interspersed, String data, int index) throws HSMException; /** * getKey * * @param inInterspersed String * @param outInterspersed String * @param index int */ public String getKey(String inInterspersed, String outInterspersed, int index) throws HSMException; /** * 解密数据 * @param interspersed * @param data String * @param index int * @return String * @throws HSMException */ public String getDecryption(String interspersed, String data, int index) throws HSMException; /** * 取得MAC * @param interspersed * @param challenge String * @param data String * @return String * @throws HSMException */ public String getMAC(String interspersed, String data, int index) throws HSMException; } 异常类: ackage com.microapp.business.hsm; /** *

Title:

* *

Description:

* *

Copyright: Copyright (c) 2005

* *

Company:

* * @author microapp * @version 1.0 */ public class HSMException extends Exception { String message; public HSMException() { } public HSMException(String errmsg) { super(errmsg); } public HSMException(int errCode) { switch(errCode) { case 80: message - "命令不可识别!"; break; case 81: message - "报文长度错误!"; break; default: message - "其他错误!"; } } } 实现文件 package com.microapp.business.hsm; /** *

Title:

* *

Description:

* *

Copyright: Copyright (c) 2005

* *

Company:

* * @author me * @version 1.0 */ import java.io.*; import java.net.*; public class HSM implements IHSM { private String address = "192.168.1.88"; private int port = 8888; public HSM() { } public HSM(String addr, int port) { this.address = addr; this.port = port; } public void setAddress(String addr) { this.address = addr; } public String getAddress() { return address; } public void setPort(int port) { this.port = port; } public int getPort() { return port; } /** * 加密 * @param interspersed String * @param data String * @param index int * @return String * @throws HSMException */ public String getEncryption(String interspersed, String data, int index) throws HSMException { System.out.println("Hava the data request at HSMe " data); int l = data.length(); if(l != 16) { throw new HSMException("Data length error!"); } Socket Client; DataInputStream InputS; DataInputStream KeyS; PrintStream OutputS; byte[] sendbuf = new byte[45]; byte[] recvbuf = new byte[64]; int i = 0; byte b1 = 0; byte b2 = 0; try { Client = new Socket(address, port); InputS = new DataInputStream(Client.getInputStream()); OutputS = new PrintStream(Client.getOutputStream()); KeyS = new DataInputStream(System.in); sendbuf[0] = 0; //长度(高) sendbuf[1] = 45; //长度(低) sendbuf[2] = (byte)0xB0; //命令代码 sendbuf[3] = 1; //密钥索引 sendbuf[4] = 24; //密钥长度 sendbuf[5] = 0; //密钥 for(i = 0; i < 24; i ) { sendbuf[5 i] =(byte)(Integer.parseInt(interspersed.substring((i * 2), (i * 2) 2), 16)); } sendbuf[6] = 0x80; //计算方式:80-加密 sendbuf[7] = 0x00; //计算数据长度(高) sendbuf[8] = 8; //计算数据长度(低) sendbuf[9] = 0; //计算数据 for(i = 0; i < 8; i ) { sendbuf[9 i] =(byte)(Integer.parseInt(data.substring((i * 2), (i * 2) 2), 16)); } OutputS.write(sendbuf); l = InputS.read(recvbuf); Client.close(); if (l < 6) { throw new HSMException("Return data length error." Integer.toHexString(l)); } if((recvbuf[3] != 0)) { throw new HSMException("Return data error." Integer.toHexString(recvbuf[3]).toUpperCase()); } l = (recvbuf[4] * 256 recvbuf[5]); StringBuffer sb = new StringBuffer(); String s = new String(); for(i = 0; i < l; i ) { s = Integer.toHexString(recvbuf[i 6]).toUpperCase(); if(s.length() == 1) { sb.append("0" s); } else if(s.length() > 2) { sb.append(s.substring(s.length() - 2, s.length())); } else { sb.append(s); } } return sb.toString(); } catch(IOException e) { throw new HSMException("IOException Happened" e.getMessage()); } } /** * 解密 * @param interspersed String * @param data String * @return String * @throws HSMException */ public String getDecryption(String interspersed, String data, int index) throws HSMException { System.out.println("Hava the data request at HSMd " data); int l = data.length(); if((l % 2) != 0) { throw new HSMException("Data length error!"); } Socket Client; DataInputStream InputS; DataInputStream KeyS; PrintStream OutputS; byte[] sendbuf = new byte[45]; byte[] recvbuf = new byte[64]; int i = 0; byte b1 = 0; byte b2 = 0; try { Client = new Socket(address, port); InputS = new DataInputStream(Client.getInputStream()); OutputS = new PrintStream(Client.getOutputStream()); KeyS = new DataInputStream(System.in); sendbuf[0] = 0; //长度(高) sendbuf[1] = 45; //长度(低) sendbuf[2] = (byte)0xB0; //命令代码 sendbuf[3] = 1; //密钥索引 sendbuf[4] = 24; //密钥长度 sendbuf[5] = 0; //密钥 for(i = 0; i < 24; i ) { sendbuf[5 i] =(byte)(Integer.parseInt(interspersed.substring((i * 2), (i * 2) 2), 16)); } sendbuf[6] = 0x81; //计算方式:81-解密 sendbuf[7] = 0x00; //计算数据长度(高) sendbuf[8] = (byte)(l / 2); //计算数据长度(低) sendbuf[9] = 0; //计算数据 for(i = 0; i < (l / 2); i ) { sendbuf[9 i] =(byte)(Integer.parseInt(data.substring((i * 2), (i * 2) 2), 16)); } OutputS.write(sendbuf); i = InputS.read(recvbuf); Client.close(); if(i < 6) { throw new HSMException("Return data length error." Integer.toHexString(i)); } if((recvbuf[3] != 0)) { throw new HSMException("Return data error." Integer.toHexString(recvbuf[3]).toUpperCase()); } l = (recvbuf[4] * 256 recvbuf[5]); StringBuffer sb = new StringBuffer(); String s = new String(); for(i = 0; i < l; i ) { s = Integer.toHexString(recvbuf[i 6]).toUpperCase(); if(s.length() == 1) { sb.append("0" s); } else if(s.length() > 2) { sb.append(s.substring(s.length() - 2, s.length())); } else { sb.append(s); } } return sb.toString(); } catch(IOException e) { throw new HSMException("IOException Happened" e.getMessage()); } } /** * 获取MAC * @param interspersed String * @param challenge String :随机数 * @param data String :加密数据 * @return String * @throws HSMException */ public String getMAC(String interspersed, String data, int index) throws HSMException { Socket Client; DataInputStream InputS; DataInputStream KeyS; PrintStream OutputS; byte[] sendbuf = new byte[64]; byte[] recvbuf = new byte[64]; int i = 0; byte b1 = 0; byte b2 = 0; try { int l = data.length(); if ((l % 2) != 0) { throw new HSMException("Data length must be 2 times."); } Client = new Socket(address, port); InputS = new DataInputStream(Client.getInputStream()); OutputS = new PrintStream(Client.getOutputStream()); KeyS = new DataInputStream(System.in); sendbuf[0] = 0x00; //长度 sendbuf[1] = (byte) (l 12); //长度 sendbuf[2] = (byte) 0xB0; //命令代码 sendbuf[3] = 1; //密钥索引 sendbuf[4] = 24; //密钥长度 sendbuf[5] = 0; //密钥 for(i = 0; i < 24; i ) { sendbuf[5 i] =(byte)(Integer.parseInt(interspersed.substring((i * 2), (i * 2) 2), 16)); } sendbuf[6] = 0x82; //计算方式:82-计算MAC sendbuf[7] = 0; //计算数据长度 sendbuf[8] = (byte) i; //计算数据长度 sendbuf[9] = 0; //计算数据 for (i = 0; i < (l / 2); i ) { sendbuf[37 i] =(byte)(Integer.parseInt(data.substring((i * 2), (i * 2) 2), 16)); } OutputS.write(sendbuf); i = InputS.read(recvbuf); Client.close(); if (i < 6) { throw new HSMException("Return data length error." Integer.toHexString(i)); } if ( (recvbuf[3] != 0)) { throw new HSMException("Return data error." Integer.toHexString(recvbuf[3]).toUpperCase()); } l = (recvbuf[4] * 256 recvbuf[5]); StringBuffer sb = new StringBuffer(); String s = new String(); for (i = 0; i < l; i ) { s = Integer.toHexString(recvbuf[i 6]).toUpperCase(); if(s.length() == 1) { sb.append("0" s); } else if(s.length() > 2) { sb.append(s.substring(s.length() - 2, s.length())); } else { sb.append(s); } } return sb.toString(); } catch (IOException e) { throw new HSMException("IOException Happened" e.getMessage()); } } } 为在应用服务器中能够实现逻辑数据组合,我建立了一个无状态session bean.在bean主要是实现数据的打包和转换. package com.microapp.business; import javax.ejb.SessionBean; import javax.ejb.SessionContext; import javax.ejb.CreateException; import com.vsc.ets.business.hsm.*; import java.util.Random; public class HSMModuleBean implements SessionBean { public static final int EXTERNAL_AUTHEN_KEY = 0x46; public static final int INTERNAL_AUTHEN_KEY = 0x45; public static final int MAC_KEY = 0x44; public static final int GENERAL_KEY = 0x41; SessionContext sessionContext; IHSM hsm = new HSM("192.168.1.88", 8888); Random rd = new Random(); String challenge; public void ejbCreate() throws CreateException { } public void ejbRemove() { } public void ejbActivate() { } public void ejbPassivate() { } public void setSessionContext(SessionContext sessionContext) { this.sessionContext = sessionContext; } public String getMAC(String s1, String s2, String s3, String challenge, String data) { try { String interspersed = s1 s2 s3; return hsm.getMAC(interspersed, challenge, MAC_KEY); } catch (Exception ex) { return null; } } public boolean internalAuthentication(String s1, String s2, String s3, String data) { String interspersed = s1 s2 s3; try { String s = hsm.getDecryption(interspersed, data, INTERNAL_AUTHEN_KEY); System.out.println("HSM internal authentication: " s " challenge: " challenge); if(s.equals(challenge)) { return true; } else { return false; } } catch(HSMException ex) { return false; } } public String[] externalAuthentication(String s1, String s2, String s3, String data) { String interspersed = s1 s2 s3; String[] s = new String[2]; this.challenge = "1234567887654321"; try { s[0] = hsm.getEncryption(interspersed, data, EXTERNAL_AUTHEN_KEY); s[1] = this.challenge; System.out.println("Ext: Encryption : " s[0] " Challenge: " s[1]); return s; } catch(HSMException ex) { return null; } } public String provideEncryption(String interspersed, String data) { try { return hsm.getEncryption(interspersed, data, GENERAL_KEY); } catch (Exception ex) { return null; } } public String provideDecryption(String interspersed, String data) { try { return hsm.getDecryption(interspersed, data, GENERAL_KEY); } catch (Exception ex) { return null; } } } 该过程在实践中应用,完全与硬加密机HSM相同.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值