2015-12-28 33 views
-1

我已经使用DES加密来加密/解密数据。这段代码工作正常。但是现在这个代码在带有填充错误的Linux盒子上失败,在Windows盒子上我没有看到这个问题。 这些是我的观察鉴于最后的块没有正确填充DES

  • 旧的加密密钥工作正常。产生的较新的导致不能在Linux机器上的Windows机器上的问题
  • 奔跑

任何人都可以让我知道什么可能导致这个问题?

这里是我的代码

/** 
* Generate the private key using the passed string. 
* 
* @param keyGeneratorString 
*   : The string which is to be used to generate the private key. 
* @return : SecretKey else null. 
*/ 
public SecretKey getKey(String keyGeneratorString) { 
    SecretKeyFactory keyFactory = null; 
    DESKeySpec keySpec = null; 
    try { 
     // only the first 8 Bytes of the constructor argument are used 
     // as material for generating the keySpec 
     keySpec = new DESKeySpec(keyGeneratorString.getBytes("UTF-8")); 
     // Get the DES encryption standard instance 
     keyFactory = SecretKeyFactory.getInstance("DES"); 
     // Generate and return the key. 
     return keyFactory.generateSecret(keySpec); 
    } catch (UnsupportedEncodingException uee) { 
     logger.error("****** Error while generating key : " 
       + uee.getMessage()); 
    } catch (InvalidKeyException ike) { 
     logger.error("****** Error while generating key : " 
       + ike.getMessage()); 
    } catch (NoSuchAlgorithmException e) { 
     logger.error("****** Error while generating key : " 
       + e.getMessage()); 
    } catch (InvalidKeySpecException e) { 
     logger.error("****** Error while generating key : " 
       + e.getMessage()); 
    } 
    // There was error while generating the key hence return null. 
    return null; 
} 

/** 
* Encrypt the string using the SecretKey. 
* 
* @param stringToBeEncrypted 
*   : The String to be encrypted. 
* @param key 
*   : The secret key to be used for encryption. 
* @return : Encrypted byte[] or null. 
*/ 
public byte[] encrypt(String stringToBeEncrypted, SecretKey key) { 
    Cipher cipherInst; 
    try { 
     cipherInst = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
     cipherInst.init(Cipher.ENCRYPT_MODE, key);// cipher is not thread 
                // safe 
     byte[] encrypted = cipherInst.doFinal(stringToBeEncrypted 
       .getBytes()); 
     return encrypted; 
    } catch (NoSuchAlgorithmException e) { 
     logger.error("****** Error while encrypting : " 
       + e.getMessage()); 
    } catch (NoSuchPaddingException e) { 
     logger.error("****** Error while encrypting : " 
       + e.getMessage()); 
    } catch (InvalidKeyException e) { 
     logger.error("****** Error while encrypting : " 
       + e.getMessage()); 
    } catch (IllegalBlockSizeException e) { 
     logger.error("****** Error while encrypting : " 
       + e.getMessage()); 
    } catch (BadPaddingException e) { 
     logger.error("****** Error while encrypting : " 
       + e.getMessage()); 
    } 
    return null; 
} 

/** 
* Decrypt the string using the SecretKey. 
* 
* @param stringToBeDecrypted : byte[] to be decrypted. 
* @param key : The secret key to be used for decryption. 
* @return : Decrypted byte[] or null. 
*/ 
public byte[] decrypt(byte[] stringToBeDecrypted, SecretKey key) { 
    Cipher cipherInst; 
    try { 
     cipherInst = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
     cipherInst.init(Cipher.DECRYPT_MODE, key); 
     byte[] original = cipherInst 
       .doFinal(stringToBeDecrypted); 
     return original; 
    } catch (NoSuchAlgorithmException e) { 
     logger.error("****** Error while decrypting : " 
       + e.getMessage()); 
    } catch (NoSuchPaddingException e) { 
     logger.error("****** Error while decrypting : " 
       + e.getMessage()); 
    } catch (InvalidKeyException e) { 
     logger.error("****** Error while decrypting : " 
       + e.getMessage()); 
    } catch (IllegalBlockSizeException e) { 
     logger.error("****** Error while decrypting : " 
       + e.getMessage()); 
    } catch (BadPaddingException e) { 
     logger.error("****** Error while decrypting : " 
       + e.getMessage()); 
    } 
    return null; 
} 
+1

看起来很好(除了使用DES,使用ECB和不验证密文)。你如何在发送者和接收者之间传输字节?你似乎遇到了“新钥匙”的问题。你能举一个这样一个新钥匙的例子吗? –

+0

检查解密的最后一个块以确定填充,只有几个填充方法,并且只有一个确实应该使用:PKCS#7(或PKCS#5,相同的算法)。添加示例将从“好”和“坏”解密的最后一个块开始。 – zaph

回答

2

将字符串转换为始终使用相同的编码字节时要小心。此行

byte[] encrypted = cipherInst.doFinal(stringToBeEncrypted 
      .getBytes()); 

使用您的计算机的默认字符编码,这在Linux和Windows之间可能会有所不同。像生成keySpec一样使用“UTF8”等一致编码。

byte[] encrypted = cipherInst.doFinal(stringToBeEncrypted 
      .getBytes("UTF-8")); 

请注意,“填充错误”通常不是这样的事情;这是一个非常误导性的错误信息。

+1

更改加密输入编码(或更确切地说,使用固定的编码)不应改变解密错误上的任何内容。这是别的。 –

相关问题