4

メッセージの暗号化と復号化に暗号を使用しています。

public String encrypt(String string) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
  cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
  byte[] stringBytes = string.getBytes("UTF-8");
  byte[] encryptedBytes = cipher.doFinal(stringBytes);
  return android.util.Base64.encodeToString(encryptedBytes, android.util.Base64.DEFAULT);
}

public String decrypt(String string) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
  cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
  byte[] stringBytes = android.util.Base64.decode(string.getBytes(), android.util.Base64.DEFAULT);
  byte[] decryptedBytes = cipher.doFinal(stringBytes);
  return new String(decryptedBytes,"UTF-8");
}

何らかの理由で、Base64 を使用して文字列をエンコードおよびデコードしていますが、それでもこのエラーが発生します。

javax.crypto.IllegalBlockSizeException: 復号化で最後のブロックが不完全です

私は何を間違っていますか?

編集:

これは私の JSONObject です - 「m」を解読しようとしています:

{"m":"Cu7FR2be0E6ZP2BrZaLU2ZWQSfycNg0-fPibphTIZno\r\n"}

奇妙なことは、エラーが Android でのみ表示されることです。私のサーバーは Java で書かれており、Apache Base64 エンコーダーを使用しています。

4

2 に答える 2

5

あなたのコードは私には問題ないようです。デコードする前に「UTF-8」を追加してみてください。

byte[] stringBytes = android.util.Base64.decode(string.getBytes("UTF-8"), android.util.Base64.DEFAULT);

編集

これは、BouncyCastle とパスワードベースの AES 暗号化を使用する暗号化/復号化を行う Security Utility クラスの例です。

public class SecurityUtils {

public static final String KEY_DERIVATION_ALGORITHM = "PBKDF2WithHmacSHA1";

private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";

private static final String DELIMITER = "]";

private static final int KEY_LENGTH = 256;

private static final int ITERATION_COUNT = 1000;

private static final int SALT_LENGTH = 8;

private static SecureRandom random = new SecureRandom();

static {
    Security.addProvider(new org.spongycastle.jce.provider.BouncyCastleProvider());
}


public static String encrypt(Context context, String plaintext)
        throws Exception {
    byte[] salt = generateSalt();
    return encrypt(plaintext, getKey(salt, getPassword(context)), salt);
}

private static String encrypt(String plaintext, SecretKey key, byte[] salt)
        throws Exception {
    try {
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");

        byte[] iv = generateIv(cipher.getBlockSize());
        IvParameterSpec ivParams = new IvParameterSpec(iv);

        cipher.init(Cipher.ENCRYPT_MODE, key, ivParams);
        byte[] cipherText = cipher.doFinal(plaintext.getBytes("UTF-8"));

        if (salt != null) {
            return String.format("%s%s%s%s%s",
                    new String(Base64.encode(salt)), DELIMITER, new String(
                            Base64.encode(iv)), DELIMITER, new String(
                            Base64.encode(cipherText)));
        }

        return String.format("%s%s%s", new String(Base64.encode(iv)),
                DELIMITER, new String(Base64.encode(cipherText)));
    } catch (Throwable e) {
        throw new Exception("Error while encryption", e);
    }
}

public static String decrypt(Context context, String ciphertext)
        throws Exception {
    return decrypt(ciphertext, getPassword(context));
}

private static String decrypt(String ciphertext, String password)
        throws Exception {
    String[] fields = ciphertext.split(DELIMITER);
    if (fields.length != 3) {
        throw new IllegalArgumentException("Invalid encypted text format");
    }
    try {
        byte[] salt = Base64.decode(fields[0]);
        byte[] iv = Base64.decode(fields[1]);
        byte[] cipherBytes = Base64.decode(fields[2]);

        SecretKey key = getKey(salt, password);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");
        IvParameterSpec ivParams = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE, key, ivParams);
        byte[] plaintext = cipher.doFinal(cipherBytes);
        String plainrStr = new String(plaintext, "UTF-8");

        return plainrStr;
    } catch (Throwable e) {
        throw new Exception("Error while decryption", e);
    }
}

private static String getPassword(Context context) {

    return "My secret password";
}

private static SecretKey getKey(byte[] salt, String password)
        throws Exception {
    try {
        KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt,
                ITERATION_COUNT, KEY_LENGTH);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(
                KEY_DERIVATION_ALGORITHM, "BC");
        byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
        return new SecretKeySpec(keyBytes, "AES");
    } catch (Throwable e) {
        throw new Exception("Error while generating key", e);
    }
}

private static byte[] generateIv(int length) {
    byte[] b = new byte[length];
    random.nextBytes(b);

    return b;
}

private static byte[] generateSalt() {
    byte[] b = new byte[SALT_LENGTH];
    random.nextBytes(b);

    return b;
}

}

于 2012-12-24T15:34:13.573 に答える