2013-03-11 3 views
1

Java 클라이언트에서 메시지를 수신하는 Java HTTP 서버가 있습니다.Java 암호화 : Java 암호화 : javax.crypto.IllegalBlockSizeException : 패딩 암호로 해독 할 때 입력 길이가 8의 배수 여야합니다.

모두 서버와 클라이언트 사용 같은 암호화 한 클래스 :

public class Encrypter { 

    private Cipher cipher; //The encryption cipher object 
public static final String ALGORITHM = "Blowfish"; //Encryption Algorithm 

    /** 
    * Constructor 
    */ 
    public Encrypter() 
    {  
     try { 
      initlizeCipher(); 
     } catch (Throwable e) {  
      ServerSettings.LOG.logError(e); 
      e.printStackTrace(); 

     } 
    } 

    /** 
    * Initialize the Cipher object 
    * @throws NoSuchAlgorithmException 
    * @throws NoSuchPaddingException 
    */ 
    private void initlizeCipher() throws NoSuchAlgorithmException, NoSuchPaddingException 
    {  
     cipher = Cipher.getInstance(ServerSettings.ALGORITHM); 
    } 

    /** 
    * Encrypt a String 
    * @param string String to encrypt 
    * @return an encrypted String 
    * @throws InvalidKeyException 
    * @throws IllegalBlockSizeException 
    * @throws BadPaddingException 
    * @throws UnsupportedEncodingException 
    */ 
    public synchronized String encrypt(String string) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException 
    { 
     cipher.init(Cipher.ENCRYPT_MODE, ServerSettings.SECRECT_KEY_SPEC); 
     byte[] stringBytes = string.getBytes("UTF-8"); 
     byte[] encryptedBytes = cipher.doFinal(stringBytes); 
     return Base64.encodeBytes(encryptedBytes);  
    } 

    /** 
    * Decrypt a String 
    * @param string String to decrypt 
    * @return a decrypted String 
    * @throws InvalidKeyException 
    * @throws IllegalBlockSizeException 
    * @throws BadPaddingException 
    * @throws IOException 
    */ 
    public synchronized String decrypt(String string) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException 
    {  
     cipher.init(Cipher.DECRYPT_MODE, ServerSettings.SECRECT_KEY_SPEC); 
     byte[] decryptedBytes = Base64.decode(string.getBytes());  
     byte[] encryptedBytes = cipher.doFinal(decryptedBytes); 
     return new String(encryptedBytes,"UTF-8"); 
    } 
} 

변수가 전송 될 때 내가 POST 메서드를 통해 서버에 메시지를 보낸다는 다음과 같습니다 m=encryptedMessage.

어떤 이유에서 내가 항상

를 얻을 수
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher 

하고 난 서버 측에서 수신 한 메시지를 해독 할 수 아니에요 ..

나는 처음에는 메시지가 고장 났을 것이라고 생각했지만 .. 그렇지 않다.

어떤 아이디어?

갱신 1 :

이상한 것은이 서버에 일부 메시지가 제대로 해독된다는 것입니다 일부는 그 오류를 반환합니다. 좋은 메시지 :

zuhRpmbtH0xSmv6cnBFkAxaGFmRbDP/97LwF4bcDyhANCTLb4afBzFpP3GI1pGFLok03GRQVCwi81Hsp            bCpGtuoIVY9cqWYDzNFgOCx5w2sboR2Qx6oxtTSIFIzj1XadQdk9V8lCxcCVVYEH8vA3tph63wU6qJOo            OyROz0OJauLBEiWbn5OUQxJ7Yz9Qc1wzl8z7UQb71v4pswF69c1CM/LWWmAzBDCjlRQ5YIB9wN8mBgoC            t8Ngt38XkCg/yRHh0EpXYQfrgP6Ls5I8/FY8BQorMy/le5y2 

나쁜 메시지 :이 메시지는 모두이 같은 방식으로 전송되고 테스트를 위해 System.out에 인쇄됩니다

cjj7yzW v3NDtbIJXurrrf318DcY PBk2inzSfz qoIaTKns2tWvR7ftOKK30XY VAlXDrQlyTLatgKA            S4IkAIK3lXQKNcwPh87CybHrTqD3HWEM3tqkpVWdB7GNmpHYsITTLrWsBvaMeDcXEr/gr9KYSZ0ks0gR            z12jHxPiZoSKHdy5nZ4zShHUy/wlkslmjFvA1G8A15nTVBhjBI GWSh54tyBZF113lL pm5eZNkZrqzo            RWI2QAjfqNPzCpV0tqd/pEO70vdSLbCYi7V0bVQNW2KpBv3Hj3VOTCP92k62/iQhIY4F VuMo2UTgGWV            1fqoelrl/eelAvsZO8YNC5/2KTKw2sDFaTOwW9R12AgeyzOuhkKQQro2Umd0KoiGnYL9AaQ6 T2MBnLK            ZyROHh3cvI T9chPlGfmUHbCN2f3pHoF5rb383KpJNjvlnmnwtaEhQYw8TQjj4PLenK24Hpcs4 wO8gu            XSrUglFzLIkkwjvsA5AyTHx/jP9AwMSnWjDwco184YQGAePeM8PYy42oMOaw7Pg/3jWFy1uOzFok2LN9            RJWv1iyXejh5s9zXoAT3kywICQygK2YTLZNIS1d5lc0H0f15EN6itZhaR0YnslhYGmH1KcNwdMWhBKsf            PytWnK0N8AzUVzt4P4mtmGSuaLi2t54J2pv7m7/c6WjTi1/E16rd3QyWkmXrghSshOJNRRwcydlhhTLH            drHTEFaXSPZyVFqlaFu4 f5kxiBa6ewglKHe6zbmRyM15Mq3lRj8Ab/RWBd2tgvaEO/vhw 

. 좋은 메시지가 아마도 블록 오류 메시지를 제공하지 않는 동안 u가 나쁜 메시지가 어떤 이유로 공백을 가질 수 있음을 알 수 있습니다. 어떻게 해결할 수 있습니까?

업데이트 2 :

내 코드에 파고 후 나는 내 문제는 POST 메서드 매개 변수를 구문 분석하는 기능 안에있는 것을 발견했습니다.

: 나는

이 점점 후 URLDECODE 해독 내 암호기로 이동 내 구문 분석 코드입니다 ... 내가 인코딩의 전문가 합니다만 Base64로 던져 POST의 URLEcoding을 인코딩 지나가는 약간의 문제가 말할 수 없다 개인 무효 parseQuery (문자열 쿼리, HashMap의 매개 변수) 예외 : UnsupportedEncodingException {

if (query != null) { 
    String pairs[] = query.split("[&]"); 

    for (String pair : pairs) 
    { 
     String param[] = pair.split("[=]"); 
     String key = null; 
     String value = null; 
     if (param.length > 0) 
      key = URLDecoder.decode(param[0], "UTF-8");//System.getProperty("file.encoding"));     

     if (param.length > 1) 
      value = URLDecoder.decode(param[1], "UTF-8");//System.getProperty("file.encoding"));     

     if (parameters.containsKey(key)) 
     { 
      Object obj = parameters.get(key); 
      if(obj instanceof List<?>) 
      { 
       @SuppressWarnings("unchecked") 
       List<String> values = (List<String>)obj; 
       values.add(value); 
      } 
      else if(obj instanceof String) 
      { 
       List<String> values = new ArrayList<String>(); 
       values.add((String)obj); 
       values.add(value); 
       parameters.put(key, values); 
      } 
     } 
     else 
      parameters.put(key, value);     
    } 
} 

}

어떤 아이디어를 던져?

+0

무엇이'ServerSettings.ALGORITHM'입니까? 귀하의 질문에 실제 가치를 추가하십시오. 수갑을 벗어 버리면, 당신이 스트림 암호 대신 블록 암호를 사용하고있는 것처럼 보입니다. – Perception

+1

알고리즘은 Blowfish입니다 –

+0

전체 알고리즘 문자열을 포함 할 수 있습니까? 기본적으로'ServerSettings.ALGORITHM' 값을 덤프하여 질문에 포함하십시오. – Perception

답변

1

많은 테스트와 울기 후에 미세하게 :) 나는 처음부터 의심 스러웠던 것을 발견했습니다.

URL을 통해 데이터를 전달할 때 (POST \ GET이든간에) 먼저 클라이언트 측에서 URL 인코딩을 먼저 수행하고 처리하기 전에 서버 측에서 URL 디코딩해야합니다. 자바의 큰 URLEncoderURLDecoder 클래스에

덕분에 당신은 쉽게 작업을 수행 할 수 있습니다

// URL에 대한 데이터를 인코딩 보내기 전에 - (charset_name을, your_data) 클라이언트 측에게 URLEncoder.encode을; // charset_name - 권장 사항은 "UTF-8"입니다.

// 데이터 수신 후 - 서버 측 데이터 - 서버 측 URLDecoder.decode (your_data, charset_name); // charset_name - 권장 사항은 "UTF-8"입니다.

1

나는 어제 비슷한 문제에 직면했다. 바이트를 클라이언트 측에서 base64로 인코딩하고 서버 측에서 사용하기 전에 디코딩하여 해결했습니다.

이 링크를 참조 - [암호] : http://www.velocityreviews.com/forums/t645364-java-string-encryption-decryption.html

는 SO 기본적으로 이것은 당신이해야 할 일입니다 - 문자열에서 바이트 배열을 가져

클라이언트 측

  • 에서
  • 암호화하십시오.
  • 인코딩 바이트 배열
  • 바이트 배열 복호화를 얻기 위해 서버 측

    • 디코드에

    부호화 데이터가 base64 인코딩베이스 64을 이용하여 바이트 배열.

  • 이 바이트 배열을 사용하여 문자열을 구성합니다.
+2

자세한 답변을 주셔서 감사합니다. 그러나 제 코드를 읽었습니까? 그게 정확히 내가 한 짓이야 .. –

0

오라클/썬에서 JCE 정책 jar 파일을 다운로드하고 무제한으로 배치하고이를 JVM 아래에 두십시오. Java 암호화에 대한 나의 경험에서 볼 때 암호화 할 때 직면하게 될 문제의 90 %는 JVM/JDK가 강력하지만 제한적인 강도 정책을 사용하고 252k 이상의 알고리즘을 사용하려고 할 때마다 시작됩니다. 이상한 실수를 던지기.

관련 문제