0

私はAES/GCM/NoPaddingJavaで暗号化を使用しています(私はそれにかなり慣れていません)。私が正しく理解している場合、GCMは暗号化されたメッセージが操作されたかどうかを認識し、そうであれば復号化すべきではありません。このアンサーに記載されているように:

認証 TAG は復号化への入力です。誰かが関連付けられたデータまたは暗号化されたデータを改ざんした場合、GCM 復号化はこれに気づき、データを出力しません (またはエラーを返し、受信したデータを処理せずに破棄する必要があります)。

ただし、私のコードでは、暗号化されたメッセージ (メッセージ部分またはタグ部分) を変更すると、エラーは発生せず、メッセージは復号化されます (もちろん異なります)。メッセージは正しく復号化されませんが、別のキーを提供してもエラーは発生しません...

私は何を間違っていますか?以下のコードを参照してください。

ユーティリティ クラス:

public class CryptoUtils {

public static byte[] encrypt(byte[] key, byte[] iv, byte[] input) throws GeneralSecurityException {
    try {
        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");

        IvParameterSpec ivspec = new IvParameterSpec(iv);

        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivspec);

        int outputLength = cipher.getOutputSize(input.length);
        byte[] output = new byte[outputLength];
        int outputOffset = cipher.update(input, 0, input.length, output, 0);
        cipher.doFinal(output, outputOffset);

        return output;
    } catch (NoSuchAlgorithmException e) {
        Timber.wtf(e);
    }
    return null;
}

public static byte[] decrypt(byte[] key, byte[] iv, byte[] encrypted) throws GeneralSecurityException {
    try {
        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
        IvParameterSpec ivspec = new IvParameterSpec(iv);

        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivspec);

        return cipher.doFinal(encrypted);
    } catch (NoSuchAlgorithmException e) {
        Timber.wtf(e);
    }
    return null;
}
}

エラーをスローしないコード:

    byte[] key = getKey();
    byte[] iv = generateIv();
    byte[] message = "hello".getBytes();

    byte[] encrypted = CryptoUtils.encrypt(key, iv, message);

    //Split decrypted message into parts. 
    byte[] encryptedMessage = new byte[message.length];
    System.arraycopy(encrypted, 0, encryptedMessage, 0, message.length);
    byte[] tag = new byte[encrypted.length - message.length];
    System.arraycopy(encrypted, message.length, tag, 0, tag.length);

    //I am modifying the message here.
    encryptedMessage[0] = 0;
    // I am also modifying the key.
    key[2] = 0;

    //Put message and tag together.
    byte[] toDecrypt = new byte[encrypted.length];
    System.arraycopy(encryptedMessage, 0, toDecrypt, 0, encryptedMessage.length);
    System.arraycopy(tag, 0, toDecrypt, encryptedMessage.length, tag.length);

    //Still not getting any errors here.
    byte[] decrypted = CryptoUtils.decrypt(key, iv, encryptedMessage);

    byte[] decryptedMessage = new byte[message.length];
    System.arraycopy(decrypted, 0, decryptedMessage, 0, message.length);

    //Decrypted message is different than original.
    Timber.d("Decrypted message: %s", new String(decryptedMessage));
4

0 に答える 0