2012-04-17 44 views
0

我在使用帶填充的AES的Groovy(JDK 1.6)中出現「BadPaddingException:給定最終塊未正確填充」異常。BadPaddingException:在Groovy(JDK 1.6)中使用帶填充的AES給出最終塊未正確填充的異常

我嘗試運行decode()方法時使用解密來自屬性文件的加密字符串值(獨立於加密進程運行)時遇到此錯誤。 加密是單獨完成的,並存儲在一個單獨的進程中的屬性文件中。

當在主要方法中一起運行加密(編碼方法)和解密(解碼方法)時,此功能正常工作。

我瀏覽了這個stackoverflow的問題,其中1人說我解密時有一個不好的關鍵問題。

我查看存儲在文件中的iv內容,它們是相同的,存儲在正在返回的密鑰庫中的Secretkey也是一樣的。

因此,我是否在Cipher.init(..)步驟中通過密碼代碼在幕後使用SecureRandom步驟失敗。 或者我沒有正確存儲密鑰或iv填充?

我已經將iv和SecretKey存儲在單獨的文件中,以便它們可以在單獨的進程中被重新用於解密,而不管加密何時完成。

示例iv值: 在加密期間: 加密iv創建:[ - 8,95,-47,-35,77,25,113,-110,95,51,71,-110,-92, -63,-95,-17] 祕密密鑰:[email protected]

在解密期間: 讀IV:[ - 8,95,-47,-35,77,25,113, -110,95,51,71,-110,-92,-63,-95,-17] 祕密密鑰:[email protected]

TIA的任何幫助, 維傑

class AESCodec extends ... { 

public static final String IV_FILE="C:/keystore/iv-file"  
private static final String RANDOM_ALGORITHM = "SHA1PRNG"; 
private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding"; 


static encode = { String target -> 
    def cipher = getCipher(Cipher.ENCRYPT_MODE) 
    return cipher.doFinal(target.bytes).encodeBase64() 
} 

static decode = { String target -> 
    //println "target:"+target 
    println "enter decode with target:"+target 
    def cipher = getCipher(Cipher.DECRYPT_MODE) 
    println "decode cipher:"+cipher 
    return new String(cipher.doFinal(target.decodeBase64()))//<============== failing here when running decode independently 
} 

private String secretPassword 

private String getSecretKey() { 
    return "secret12" 
} 

private static getPassword() { new AESCodec().getSecretKey().getChars() } 

private static byte[] iv 

static SecretKey secretKey 
/* 
* Get key from Keystore where it is stored after creation 
*/ 
private static SecretKey createKey(Integer mode) { 
    println "createKey() mode values 1=encrypt,2=decrypt mode:"+mode 
    if (secretKey == null) { 
     if (mode== Cipher.ENCRYPT_MODE) { 
      println "inside encrypt mode in createKey()" 
      byte[] salt = "DYKSalt".getBytes() 
      SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1") 
      KeySpec spec = new PBEKeySpec(getPassword(), salt, 65536, 256) 
      SecretKey tmp = factory.generateSecret(spec) 
      SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES") 
      secretKey = secret 
      println 'inside encrypt secretKey:'+secretKey 
      //store it in keystore 
      KeyStore ks = KeyStore.getInstance("JCEKS") 
      ks.load(null, null); 
      KeyStore.SecretKeyEntry skEntry = new KeyStore.SecretKeyEntry(secretKey) 
      //key alias and passwd 
      ks.setEntry("alias", skEntry, 
       new KeyStore.PasswordProtection("fggd".toCharArray())) 
      FileOutputStream fos = null 
      try { 
       fos = new FileOutputStream(AsymmetricCipher.KEYSTORE_DIR+"aes.keystore") 
       //keystore passwd 
       ks.store(fos, "fggd".toCharArray()) 
      } finally { 

       fos?.close() 

      } 


     } else if (mode== Cipher.DECRYPT_MODE) { 


      InputStream inputStream = getKeystoreAsStream(AsymmetricCipher.KEYSTORE_DIR+"aes.keystore") 

      BufferedInputStream fis = null 
      try { 

       fis = new BufferedInputStream(inputStream) 
       println "fis:"+fis 
       //keystore passwd 
       KeyStore ks = KeyStore.getInstance("JCEKS") 
       //get key store 
       ks.load(fis, "fggd".toCharArray()) 

       //get key from keystore 
       Entry entry = ks.getEntry("alias", new KeyStore.PasswordProtection("fggd".toCharArray())) 
       KeyStore.SecretKeyEntry secretKeystoreEntry = (KeyStore.SecretKeyEntry)entry 
       secretKey = secretKeystoreEntry.getSecretKey() 
       println " returned secretKey from decrypt mode" 
      } finally { 

       fis?.close() 

      } 

     } 

    } else { 


    } 

    return secretKey 
} 


private SecretKey getKey() { 

    return secretKey 
} 

private static getCipher(mode) { 


    SecretKey secret = createKey(mode) 
    Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); 
    println "secret:"+secret.getEncoded() 
    println "cipher:"+cipher 

    if (mode == Cipher.DECRYPT_MODE) { 
     //get iv 
     iv = readIvFromFile(IV_FILE) 
     println "decrypt iv created from file:"+iv 
     IvParameterSpec ivspec = new IvParameterSpec(iv); 
     println "ivspec:"+ivspec 
     cipher.init(mode, secret,ivspec) 
     //cipher.init(mode, secret) 
    } else { 

     //save that to IV_FILE 
     byte[] iv = generateIv(); 
     println "encrypt iv created:"+iv 
     IvParameterSpec ivspec = new IvParameterSpec(iv); 
     println "ivspec:"+ivspec 
     cipher.init(mode, secret,ivspec) 
     //iv = cipher.getIV() 
     AlgorithmParameters params = cipher.getParameters() 
     iv = params.getParameterSpec(IvParameterSpec.class).getIV() 
     saveToFile(IV_FILE,iv) 
    } 


    return cipher 

} 

private static byte[] generateIv() throws NoSuchAlgorithmException { 
    SecureRandom random = SecureRandom.getInstance(RANDOM_ALGORITHM); 
    byte[] iv = new byte[16]; 
    random.nextBytes(iv); 
    return iv; 
} 


public static void saveToFile(String fileName, 
    byte[] iv) throws IOException { 
    println "saveToFile() fileName:"+fileName 
    FileOutputStream oout = 
     new FileOutputStream(fileName); 

    try { 
     oout.write(iv); 

    } catch (Exception e) { 
     throw new IOException("Unexpected error", e); 
    } finally { 

     oout?.flush() 
     oout?.close() 
    } 
} 

private static byte[] readIvFromFile(String keyFileName) 
throws IOException { 
    println "readIvFromFile() keyFileName:"+keyFileName 

    InputStream inputStream = AsymmetricCipher.getFile(keyFileName) 

    try { 

     iv = IOUtils.toByteArray(inputStream); 

     println "read iv:"+iv 
     return iv; 
    } catch (Exception e) { 
     throw new RuntimeException("Spurious serialisation error ", e); 
    } finally { 
     inputStream = null 
     //oin?.close(); 
    } 

} 


static void main(String[] args) { 

    String message="This is just an example"; 

    if(args) { 

     def encryptedValue = encode(args[0]) 
     println "encryptedValue:"+encryptedValue //byte[] 

     String encryptedValue1=(String)(encryptedValue) 
     println "encryptedValue1:"+encryptedValue1 



     def decryptedValue = decode(encryptedValue1) 
     println "decryptedValue:"+decryptedValue 
     def decryptedValueStr = (String)decryptedValue 


    } 

// 
} 

}

+0

你可以發佈導致問題的代碼嗎?這看起來像它的代碼 – imichaelmiers 2012-04-18 00:48:24

+0

這是在嘗試單獨從編碼/加密過程運行解密/解碼時不起作用的代碼。 – Vijay 2012-04-18 16:27:27

回答

相關問題