package hamaster.gradesign.servlet; import hamaster.gradesgin.ibe.IBECipherText; import hamaster.gradesgin.ibe.IBEConstraints; import hamaster.gradesgin.ibe.IBEPlainText; import hamaster.gradesgin.ibe.core.IBEEngine; import hamaster.gradesgin.ibe.io.SecureByteArrayOutputStream; import hamaster.gradesign.daemon.EJBClient; import hamaster.gradesign.mgr.ClientManager; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 完成和客户端的交互 如分发密钥 * @author <a href="mailto:wangyeee@gmail.com">Wang Ye</a> */ @WebServlet("/client") public class ClientServlet extends HttpServlet { private static final long serialVersionUID = 1L; private ClientManager clientManager; /* * (non-Javadoc) * @see HttpServlet#HttpServlet() */ public ClientServlet() { } /* * (non-Javadoc) * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig) */ public void init(ServletConfig config) throws ServletException { super.init(config); this.clientManager = EJBClient.getInstance().getBean("clientManager", ClientManager.class); } /** * 请求格式:<br> * 操作名长度1字节<br> * 操作名最多256字节<br> * IBE加密后会话密钥384字节<br> * 请求数据(AES_256_CBC加密)若干字节 * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { EJBClient system = EJBClient.getInstance(); OutputStream out = response.getOutputStream(); InputStream in = request.getInputStream(); int aLen = in.read(); byte[] aData = new byte[aLen]; // 读取请求的操作 if (aData.length != in.read(aData)) return; String action = new String(aData); byte[] encSessKey = new byte[IBEConstraints.IBE_G_SIZE * 3]; // 读取IBE加密后的会话密钥 if (encSessKey.length != in.read(encSessKey)) return; IBECipherText cipher = new IBECipherText(); cipher.setUvw(encSessKey); cipher.setLength(48); // AES_256_CBC IBEPlainText plain = IBEEngine.decrypt(cipher, system.serverPrivateKey()); byte[] sessKey = IBEPlainText.getSignificantBytes(plain); // 解密数据 ByteArrayOutputStream buffer = new SecureByteArrayOutputStream(in.available() + 16); byte[] reqBody = null; byte[] key = new byte[32]; byte[] iv = new byte[16]; System.arraycopy(sessKey, 0, key, 0, 32); System.arraycopy(sessKey, 32, iv, 0, 16); try { int len; byte[] temp = new byte[16]; Cipher cipher0 = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher0.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv)); while ((len = in.read(temp)) > 0) { byte[] crypt = cipher0.update(temp, 0, len); buffer.write(crypt); } byte[] fin = cipher0.doFinal(); buffer.write(fin); buffer.flush(); reqBody = buffer.toByteArray(); } catch (NoSuchAlgorithmException e) { } catch (NoSuchPaddingException e) { } catch (InvalidKeyException e) { throw new IOException(e); } catch (InvalidAlgorithmParameterException e) { } catch (IllegalBlockSizeException e) { throw new IOException(e); } catch (BadPaddingException e) { throw new IOException(e); } finally { Arrays.fill(key, (byte) 0); Arrays.fill(iv, (byte) 0); buffer.close(); } byte[] resp = null; // 处理请求 try { Method method = clientManager.getClass().getMethod(action, byte[].class); resp = (byte[]) method.invoke(clientManager, reqBody); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { resp = new byte[1]; resp[0] = ClientManager.ERR_UNKNOWN_OP; e.printStackTrace(); // TODO debug } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { resp = new byte[1]; resp[0] = ClientManager.ERR_PROC_REQ; e.printStackTrace(); // TODO debug } finally { Arrays.fill(reqBody, (byte) 0); if (resp == null || resp.length < 1) { // TODO 无法处理请求 return; } } System.arraycopy(sessKey, 0, key, 0, 32); System.arraycopy(sessKey, 32, iv, 0, 16); byte[] crypt0 = null; // 将处理结果加密并返回 try { Cipher cipher0 = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher0.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv)); crypt0 = cipher0.doFinal(resp); // TODO 只返回了处理后的数据 out.write(crypt0); out.flush(); } catch (NoSuchAlgorithmException e) { } catch (NoSuchPaddingException e) { } catch (InvalidKeyException e) { throw new IOException(e); } catch (InvalidAlgorithmParameterException e) { } catch (IllegalBlockSizeException e) { throw new IOException(e); } catch (BadPaddingException e) { throw new IOException(e); } finally { Arrays.fill(key, (byte) 0); Arrays.fill(iv, (byte) 0); Arrays.fill(resp, (byte) 0); Arrays.fill(crypt0, (byte) 0); out.close(); } } }