jdk中的des加密算法

这两天程序做压力测试,发现了一个问题,在用jdk提供的des加密时,当访问量过大时,加解密时突然报错

java.lang.IllegalStateException: Cipher not initialized
    at javax.crypto.Cipher.c(DashoA12275)
    at javax.crypto.Cipher.doFinal(DashoA12275)
    at com.changda.encrypt.DESEngine.encrypt(DESEngine.java:67)
    at com.changda.encrypt.DESEngine.encrypt(DESEngine.java:106)
    at com.changda.clientapi.BaseCall.creatKey(BaseCall.java:220)
    at com.changda.util.SendXNMRequest.sendRequest(SendXNMRequest.java:50)
    at com.changda.business.service.AccountServiceImpl.login(AccountServiceImpl.java:21)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:304)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:139)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at $Proxy1.login(Unknown Source)
    at com.changda.struts.action.LoginAction.execute(LoginAction.java:71)
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
    at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
    at com.changda.util.ParseConfigfile.doFilter(ParseConfigfile.java:18)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
    at com.mas.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:122)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
    at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
    at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
    at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
    at java.lang.Thread.run(Thread.java:595)

看错误是Cipher未初始化,可代码中肯定初始化了,怀疑是jdk本身没来得及初始化,原程序中的做法是,每次解加解密,都创建一个Cipher对象,现改为,有几个密钥就创建几个静态的Cipher对象,放在hashmap中,问题解决。

修改后的java des加密 程序如下:

import java.security.*;  
import java.util.HashMap;

import javax.crypto.*;  
 
public class DESEngine {   
     
    private static HashMap encryptCipherMap=new HashMap();
    private static HashMap decryptCipherMap=new HashMap();
   
  

     public static String byteArr2HexStr(byte[] arrB) throws Exception {  
      int iLen = arrB.length;  
     
      StringBuffer sb = new StringBuffer(iLen * 2);  
      for (int i = 0; i < iLen; i++) {  
       int intTmp = arrB[i];  

       while (intTmp < 0) {  
        intTmp = intTmp + 256;  
       }  
     
       if (intTmp < 16) {  
        sb.append("0");  
       }  
       sb.append(Integer.toString(intTmp, 16));  
      }  
      return sb.toString();  
     }  
     
     
     public  byte[] hexStr2ByteArr(String strIn) throws Exception {  
      byte[] arrB = strIn.getBytes();  
      int iLen = arrB.length;  
     
      byte[] arrOut = new byte[iLen / 2];  
      for (int i = 0; i < iLen; i = i + 2) {  
       String strTmp = new String(arrB, i, 2);  
       arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);  
      }  
      return arrOut;  
     }  
     
       private static DESEngine single = new DESEngine();

        private DESEngine() {
        }

        public static DESEngine getInstance() {
            return single;
        }
       
    private void init(String strKey)throws Exception{
        Security.addProvider(new com.sun.crypto.provider.SunJCE());  
      Key key = getKey(strKey.getBytes());  
      if(encryptCipherMap.get(strKey)==null){
          Cipher encryptCipher = Cipher.getInstance("DES/ECB/NoPadding","SunJCE");
          encryptCipher.init(Cipher.ENCRYPT_MODE, key);
          encryptCipherMap.put(strKey, encryptCipher);
      }
     
      if(decryptCipherMap.get(key)==null){
          Cipher decryptCipher = Cipher.getInstance("DES/ECB/NoPadding","SunJCE");  
          decryptCipher.init(Cipher.DECRYPT_MODE, key);
          decryptCipherMap.put(strKey, decryptCipher);
      }
    }
     public byte[] encrypt(byte[] arrB,String key) throws Exception {  
      return ((Cipher)encryptCipherMap.get(key)).doFinal(arrB);  
     }  
      
     
     
     public byte[] decrypt(byte[] arrB,String key) throws Exception {  
      return ((Cipher)decryptCipherMap.get(key)).doFinal(arrB);  
     }  
     
     
     
     private Key getKey(byte[] arrBTmp) throws Exception {  
      byte[] arrB = new byte[8];  
      for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {  
       arrB[i] = arrBTmp[i];  
      }    
      Key key = new javax.crypto.spec.SecretKeySpec(arrB, "DES");  
     
      return key;  
     }  
     
     public String encrypt(String key,String strIn) throws Exception {  
         this.init(key);
         byte[] inb = strIn.getBytes();
         int length = inb.length;
         int mod = length % 8;
         if (mod != 0) {
             mod = 8 - mod;
         }
         byte[] newin = new byte[length + mod];
         for (int u = 0; u < length; u++) {
             newin[u] = inb[u];
         }
         //给存储明文的字节数组a的不足位补0
         for (int u = length; u < newin.length; u++) {
             newin[u] = 0;
         }

          
         return byteArr2HexStr(encrypt(newin,key));  
     }  
     public String decrypt(String key,String strIn) throws Exception {
        this.init(key);
        return new String(decrypt(hexStr2ByteArr(strIn),key));  
     } 

}

 

你可能感兴趣的:(Cipher未初始化,des加密,java des加密)