4

我正在解决使用 Java 加密消息的问题,然后使用基于 AES GCM 算法的 Python 解密消息。

基于python doc,认证标签由加密器证明。 https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/#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 代码来解密消息?

4

1 回答 1

0

感谢您的领导@topaco。在此处粘贴工作代码。

import base64

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes

def decrypt():    
    key = base64.b64decode("X3uBZOZdPqJipDsyvCm/zQ==")
    iv = base64.b64decode("Oe6yP87rg8G7dJSj")
    tag = base64.b64decode("V29ybGQ=")
    print(tag)
    msg = base64.b64decode("UvqFC+sWspXrWwdV6XCc7Wahp6l5")
    ciphertext, authTag = msg[:-16], msg[-16:]
    print(ciphertext, authTag)

    deCipher = Cipher(algorithms.AES(key), modes.GCM(iv, None, len(authTag)), default_backend()).decryptor()
    deCipher.authenticate_additional_data(tag)
    computed_msg = deCipher.update(ciphertext) + deCipher.finalize_with_tag(authTag)
    print(computed_msg)

if __name__ == '__main__':
   decrypt()
于 2021-08-13T11:42:57.137 回答