Как зашифровать сообщение с помощью Java, а затем расшифровать сообщение с помощью Python для алгоритма AES GCM

Я работаю над проблемой шифрования сообщения с помощью Java, а затем расшифровываю сообщение с помощью Python на основе алгоритма AES GCM.

На основе документа Python тег аутентификации подтверждается шифровальщиком. https://cryptography.io/en/latest/hazmat/primitives/симметричное-шифрование/#cryptography.hazmat.primitives.ciphers.modes.GCM Однако в Java я не знаю, как генерируется тег аутентификации.

Вот мой пример кода Java

public class Example {

    public static final int AES_KEY_SIZE = 128; // in bits
    public static final int GCM_NONCE_LENGTH = 12; // in bytes
    public static final int GCM_TAG_LENGTH = 16; // in bytes

    public static void main(String args[]) throws Exception {

        byte[] message = "Hello".getBytes(StandardCharsets.UTF_8);

        SecureRandom secureRandom = SecureRandom.getInstanceStrong();
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(AES_KEY_SIZE, secureRandom);
        SecretKey secretKey = keyGenerator.generateKey();

        // Encrypt
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
        final byte[] nonce = new byte[GCM_NONCE_LENGTH];
        secureRandom.nextBytes(nonce);
        GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, spec);

        byte[] tag = "World".getBytes(StandardCharsets.UTF_8);
        cipher.updateAAD(tag);
        byte[] cipherText = cipher.doFinal(message);

        System.out.println(Base64.getEncoder().encodeToString(secretKey.getEncoded()));
        System.out.println(Base64.getEncoder().encodeToString(nonce));
        System.out.println(Base64.getEncoder().encodeToString(tag));
        System.out.println(Base64.getEncoder().encodeToString(cipherText));

        cipher.init(Cipher.DECRYPT_MODE, secretKey, spec);
        cipher.updateAAD(tag);
        byte[] plainText = cipher.doFinal(cipherText);

        System.out.println(new String(plainText));
    }
}

Вот мой код Python, который не работает, потому что «ValueError: тег аутентификации должен быть указан при расшифровке».

    key = base64.b64decode("X3uBZOZdPqJipDsyvCm/zQ==");
    iv = base64.b64decode("Oe6yP87rg8G7dJSj");
    tag = base64.b64decode("V29ybGQ=");
    print (tag)
    msg = base64.b64decode("UvqFC+sWspXrWwdV6XCc7Wahp6l5");

    deCipher = Cipher(algorithms.AES(key), modes.GCM(iv, None), default_backend()).decryptor()
    deCipher.authenticate_additional_data(tag)
    computed_msg = deCipher.update(msg) + deCipher.finalize()
    print (computed_msg)

Учитывая ключ, тег, одноразовый номер и шифрованный текст, мой вопрос заключается в том, как написать код Python для расшифровки сообщения?


person Turbocv    schedule 12.11.2019    source источник
comment
Тег аутентификации и дополнительные аутентифицированные данные (AAD) — это две разные вещи. Переменная тега в обоих кодах фактически обозначает AAD и должна быть соответствующим образом переименована. Кроме того, Java добавляет тег аутентификации к зашифрованному тексту. Поскольку в Python тег аутентификации и зашифрованный текст передаются отдельно, обе переменные должны быть сначала разделены в Python, например. с ciphertext = msg[:-16] и authTag = msg[-16:]. Взгляните на это .   -  person user 9014097    schedule 12.11.2019
comment
Спасибо, протестируйте код, он работает.   -  person Turbocv    schedule 12.11.2019