16

"~9?8?m???=?T?G"OpenSSL を使用して AES-256-CBC を使用して文字列を暗号化するバックエンド サーバーから受信した文字列を復号化しようとしています。コードブロックがあります:

public static String decryptText(String textToDecrypt) {
    try {

        byte[] base64TextToDecrypt = Base64.encodeBase64(textToDecrypt.getBytes("UTF-8"));

        byte[] guid = "fjakdsjkld;asfj".getBytes("UTF-8");

        byte[] iv = new byte[16];
        System.arraycopy(guid, 0, iv, 0, guid.length);
        IvParameterSpec ips = new IvParameterSpec(iv);

        byte[] secret = DECRYPTION_SECRET_HASH.getBytes("UTF-8");
        SecretKeySpec secretKey = new SecretKeySpec(secret, "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        // decryption pass
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ips);
        byte[] converted = cipher.doFinal(base64TextToDecrypt);
        System.out.println(new String(converted));

    } catch (Exception e) {
        e.printStackTrace();
        Log.e(TAG, "Decipher error for " + textToDecrypt, e);
    }
    return "";
}

残念ながら、私がに着いたとき

byte[] converted = cipher.doFinal(base64TextToDecrypt);

次の例外がスローされます。

javax.crypto.IllegalBlockSizeException: last block incomplete in decryption

何か案は?

4

3 に答える 3

9

メソッドの開始時に、文字列のプラットフォーム固有の表現をエンコードするのではなく、文字列をデコードする必要があります。

byte[] base64TextToDecrypt = Base64.decodeBase64(textToDecrypt);

またはより正確には:

byte[] bytesToDecrypt = Base64(base64TextToDecrypt);

変数に正しく名前を付ければ。

一般に、(そうしなければならないと感じて)String.getBytes(): byte[]メソッドまたはString(byte[])コンストラクターを使用するたびに、何か間違ったことをしている可能性があります。最初に何をしようとしているのかを考え、する必要がある場合はそれを指定する必要があります。

あなたの場合、converted変数の出力はおそらく文字エンコードされています。したがって、次のフラグメントを使用できます。

String plainText = new String(converted, StandardCharsets.UTF_8);
System.out.println(plainText);

あなたが今持っているものの代わりに。

于 2012-11-07T16:35:05.397 に答える
5

@owlsteadのおかげで、私は解決策を見つけることができました。すでにBase64でエンコードされた文字列をBase64でエンコードするのを間違えたのです。以下はコードチャンクによるものです。

public static String decryptText(String textToDecrypt) {
    try {
        byte[] decodedValue = Base64.decodeBase64(textToDecrypt.getBytes());

        byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        IvParameterSpec ips = new IvParameterSpec(iv);

        byte[] input = textToDecrypt.getBytes();

        Cipher cipher = Cipher.getInstance(ENCRYPTION_METHOD);

        // decryption pass
        cipher.init(Cipher.DECRYPT_MODE, SECRET_KEY, ips);
        byte[] plainText = cipher.doFinal(decodedValue);

        return new String(plainText);
    } catch (Exception e) {
        e.printStackTrace();
        Log.e(TAG, "Decipher error for " + textToDecrypt, e);
    }

    return "";
}

対応する暗号化は次のようになります

public static String encryptText(String textToEncrypt) {
    try {
        byte[] guid = "1234567890123456".getBytes("UTF-8");

        byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        IvParameterSpec ips = new IvParameterSpec(iv);

        // The secret key from the server needs to be converted to byte array for encryption.
        byte[] secret = ENCRYPTION_SECRET_HASH.getBytes("UTF-8");

        // we generate a AES SecretKeySpec object which contains the secret key.
        // SecretKeySpec secretKey = new SecretKeySpec(secret, "AES");
        Cipher cipher = Cipher.getInstance(ENCRYPTION_METHOD);
        cipher.init(Cipher.ENCRYPT_MODE, SECRET_KEY, ips);

        byte[] cipherText = cipher.doFinal(textToEncrypt.getBytes());
        byte[] base64encodedSecretData = Base64.encodeBase64(cipherText);
        String secretString = new String(base64encodedSecretData);
        return secretString;
    } catch (Exception e) {
        e.printStackTrace();
        Log.e(TAG, "Encryption error for " + textToEncrypt, e);
    }
    return "";
}
于 2012-11-08T00:30:16.943 に答える