繁体   English   中英

BadPaddingException:给定最终块,在Groovy(JDK 1.6)中未正确填充异常,使用带有填充的AES

[英]BadPaddingException: Given final block not properly padded exception in Groovy(JDK 1.6) using AES with padding

我在Groovy(JDK 1.6)中使用带有填充的AES收到“ BadPaddingException:给定的最终块未正确填充”异常。

当尝试使用从属性文件中解密加密的String值(独立于加密过程运行)来运行encode()方法时,遇到了此错误。 加密是单独完成的,并在单独的过程中存储在属性文件中。

当像main方法一样同时运行加密(编码方法)和解密(解码方法)时,此方法效果很好。

我已经浏览了这个的stackoverflow问题,其中1个说解密时我遇到了一个不好的密钥问题。

我查看了存储在文件中的iv内容,它们是相同的,存储在返回的密钥库中的Secretkey也是如此。

因此,我在Cipher.init(..)步骤上失败了吗?在此步骤中,Cipher代码在后台使用了SecureRandom。 还是我没有正确存储密钥或iv填充?

我已将iv和SecretKey存储在单独的文件中,以便可以在独立于加密完成时间的单独过程中将它们重新用于解密。

示例iv值:加密期间:创建的加密iv:[-8、95,-47,-35、77、25、113,-110、95、51、71,-110,-92,-63,-95, -17] secretKey:javax.crypto.spec.SecretKeySpec@16c11

解密期间:读取iv:[-8、95,-47,-35、77、25、113,-110、95、51、71,-110,-92,-63,-95,-17] secretKey: javax.crypto.spec.SecretKeySpec@16c11

TIA需要任何帮助,Vijay

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


  }

//
}

}

看看: http : //code.google.com/p/encryption-utils/source/browse/#svn%2Ftrunk%2Fsrc%2Fmain%2Fjava%2Fcom%2Fgoogle%2Fgoogle%2Fcode%2Fencryptionutils

这是我为简单加密编写的一个小库。 希望它能给您一些指导。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM