1

我有一个示例代码,它使用 AES-GCM-256 加密和解密字符串。

我无法理解,如何在加密器端生成身份验证标签以及如何在解密器端使用它。

实际上,这里我既不是在加密器端也不是在验证解密器端生成身份验证标签,所以它是由库本身在内部完成的。

private static String encrypt(String s, byte[] k) throws Exception {
        SecureRandom r = SecureRandom.getInstance("SHA1PRNG");
        // Generate 128 bit IV for Encryption
        byte[] iv = new byte[12]; r.nextBytes(iv);

        SecretKeySpec eks = new SecretKeySpec(k, "AES");
        Cipher c = Cipher.getInstance("AES/GCM/NoPadding");

        // Generated Authentication Tag should be 128 bits
        c.init(Cipher.ENCRYPT_MODE, eks, new GCMParameterSpec(128, iv));
        byte[] es = c.doFinal(s.getBytes(StandardCharsets.UTF_8));

        // Construct Output as "IV + CIPHERTEXT"
        byte[] os = new byte[12 + es.length];
        System.arraycopy(iv, 0, os, 0, 12);
        System.arraycopy(es, 0, os, 12, es.length);

        // Return a Base64 Encoded String
        return Base64.getEncoder().encodeToString(os);

    }

    private static String decrypt(String eos, byte[] k) throws Exception {
        // Recover our Byte Array by Base64 Decoding
        byte[] os = Base64.getDecoder().decode(eos);

        // Check Minimum Length (IV (12) + TAG (16))
        if (os.length > 28) {
            byte[] iv = Arrays.copyOfRange(os, 0, 12);
            byte[] es = Arrays.copyOfRange(os, 12, os.length);

            // Perform Decryption
            SecretKeySpec dks = new SecretKeySpec(k, "AES");
            Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
            c.init(Cipher.DECRYPT_MODE, dks, new GCMParameterSpec(128, iv));

            // Return our Decrypted String
            return new String(c.doFinal(es), StandardCharsets.UTF_8);
        }
        throw new Exception();
    }
4

0 回答 0