我在使用帶填充的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
}
//
}
}
你可以發佈導致問題的代碼嗎?這看起來像它的代碼 – imichaelmiers 2012-04-18 00:48:24
這是在嘗試單獨從編碼/加密過程運行解密/解碼時不起作用的代碼。 – Vijay 2012-04-18 16:27:27