0

パディング付きのAESを使用すると、Groovy(JDK 1.6)で「BadPaddingException:指定された最終ブロックが適切にパディングされていません」という例外が発生します。

プロパティファイルから暗号化された文字列値を復号化してdecode()メソッドを実行しようとすると、このエラーが発生します(暗号化プロセスとは独立して実行されます)。暗号化は個別に行われ、個別のプロセスでプロパティファイルに保存されました。

これは、暗号化(エンコード方式)と復号化(デコード方式)の両方がメインメソッドのように一緒に実行される場合に正常に機能します。

私はこれについてstackoverflowの問題を閲覧しましたが、そのうちの1つは、復号化時にキーに問題があると言っています。

ファイルに保存されているivの内容を確認しましたが、それらは同じであり、キーストアに保存されているシークレットキーも返されます。

それで、SecureRandomがCipherコードによって舞台裏で使用されるCipher.init(..)ステップで失敗していますか?または、キーまたは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


  }

//
}

}

4

1 に答える 1

0

見てください:http://code.google.com/p/encryption-utils/source/browse/#svn%2Ftrunk%2Fsrc%2Fmain%2Fjava%2Fcom%2Fgoogle%2Fcode%2Fencryptionutils

これは、単純な暗号化のために作成した小さなライブラリです。うまくいけば、それはあなたにいくつかの方向性を与えることができます.

于 2012-04-19T01:00:05.020 に答える