当前位置: 首页 > 面试题库 >

JAVA中的AES GCM解密绕过身份验证

扶珂
2023-03-14
问题内容

我有一些AES /
GCM加密数据,想对其解密。我想绕过身份验证解密它,因为数据不包含身份验证信息(数据由第三方应用程序加密)。我尝试使用javax.crypto包进行解密,但它始终会引发标签不匹配错误。有什么方法可以绕过此标签检查并解密数据。数据使用AES128加密,并且使用12字节初始化向量。

编辑:我得到了这个问题的临时解决方案。不知道这是否是正确的方法。

            Key key = new SecretKeySpec(hlsKey, "AES");
            GCMParameterSpec gCMParameterSpec = new     GCMParameterSpec(96, initialisationVector);
            final Cipher c = Cipher.getInstance("AES/GCM/NoPadding", "BC");
            c.init(Cipher.DECRYPT_MODE, key, gCMParameterSpec);

            byte[] nodata = new byte[len * 2];
            System.arraycopy(cipherText, 0, nodata, 0, len);
            byte[] plaindata = new byte[len * 2];
            try {

                int decrypted_index = 0;
                while (decrypted_index < len) {
                    int cp = c.update(nodata, decrypted_index, nodata.length - decrypted_index, plaindata, decrypted_index);//doFinal(nodata);
                    decrypted_index += cp;
                }
               if(decrypted_index>=len){
                   System.arraycopy(plaindata, 0, plainText, 0, len);
                   retvalue=1;
               }
            } catch (Exception e) {
                e.printStackTrace();
            }

问题答案:

是的,可以解密不带有身份验证标签的消息:如果您阅读了GCM规范,则可以看到CTR的IV只是IV,后面加上四个字节00000002(即,计数器从零开始,为计算而增加了一个)身份验证标签,然后再次输入加密计数器的起始值)。

所以这是代码,inc我用它两次来验证我的计数器代码。当然也可以简单地将最后一个字节设置为value 0x02

package nl.owlstead.so;

import java.nio.charset.StandardCharsets;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.util.Arrays;

public class DecryptGCMWithoutVerification {

    private static final int TAG_SIZE = 128;

    public DecryptGCMWithoutVerification() {
        // TODO Auto-generated constructor stub
    }

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

        // --- encryption using GCM

        Cipher gcm = Cipher.getInstance("AES/GCM/NoPadding");
        SecretKey key = new SecretKeySpec(new byte[16], "AES");
        byte[] ivBytes = new byte[12];
        GCMParameterSpec iv = new GCMParameterSpec(TAG_SIZE, ivBytes);
        gcm.init(Cipher.ENCRYPT_MODE, key, iv);
        byte[] ct = gcm.doFinal("owlstead".getBytes(StandardCharsets.US_ASCII));

        // --- decryption using underlying CTR mode

        Cipher ctr = Cipher.getInstance("AES/CTR/NoPadding");

        // WARNING: this is only correct for a 12 byte IV in GCM mode
        byte[] counter = Arrays.concatenate(ivBytes, new byte[4]);
        inc(counter);
        inc(counter);
        IvParameterSpec ctrIV = new IvParameterSpec(counter);
        ctr.init(Cipher.DECRYPT_MODE, key, ctrIV);

        byte[] pt = ctr.doFinal(ct, 0, ct.length - TAG_SIZE / Byte.SIZE);

        System.out.println(new String(pt, StandardCharsets.US_ASCII));
    }

    private static final byte inc(byte[] counter) {
        for (int i = counter.length - 1; i >= 0; i--) {
            if (++counter[i] != 0) {
                return 0;
            }
        }
        return 1;
    }

}

编辑:此代码用于无效标签或无法重新计算的标签(例如,可能缺少AAD)。如果标签完全缺失- TAG_SIZE / Byte.SIZEdoFinal请将其删除。

编辑2:请注意,这假定12字节/ 96位IV,这是GCM的默认IV大小。对于其他尺寸,您需要首先计算IV。



 类似资料:
  • 我有一些AES/GCM加密的数据,想解密它。我希望绕过身份验证对其进行解密,因为数据不包含身份验证信息(数据是由第三方应用程序加密的)。我尝试用javax.crypto包解密,它总是抛出标记不匹配错误。有没有办法绕过这个标记检查,解密数据。数据用AES128加密,使用12字节初始化向量。 编辑:我得到了这个问题的临时解决方案。不确定这是不是正确的方法。

  • 我需要连接到LDAP服务器,但出现以下错误: javax。命名。AuthenticationException:[LDAP:错误代码49-80090308:LDAPPER:DSID-0C09034,注释:AcceptSecurityContext错误,数据525,向量 用户名和密码正确,我尝试设置相同的用户并传入另一个用编写的应用程序。NET,它在那里工作,但在Java中,我收到了错误消息。 我的

  • 我正在尝试在WooCommerce Webhook API和我的节点之间创建一个集成。js后端。然而,我真的不知道应该如何使用这个秘密来验证请求。 机密:一个可选的密钥,用于生成请求正文的HMAC-SHA256哈希,以便接收方可以验证webhook的真实性。 返回以下值: :pU9kXddJPY9MG9i2ZFLNTu3TXZA 85pnwfPqmr0dg0= 签名:PjKImjr9Hk9MmId

  • 问题内容: 我看到了很多教程,展示了如何使用Java在mongodb中进行身份验证 我将mongodb配置为启用身份验证。在控制台中,我使用 使用管理员 db.auth(“ myUser”,“ newPassword”)并运行良好。 在Java中,在每个访问过的网站中,代码都是 大问题是代码对我不起作用,我也不知道为什么。我测试了显式更改为管理数据库。 这对我来说有效,但这不是解决方案,因为我试图

  • 问题内容: 问题: 我们有一个基于Spring MVC的RESTful API,其中包含敏感信息。该API应该是安全的,但是不希望随每个请求一起发送用户凭证(用户/密码组合)。根据REST准则(和内部业务要求),服务器必须保持无状态。该API将由另一台服务器以mashup方式使用。 要求: 客户端使用凭据向(不受保护的URL)发出请求;服务器返回一个安全令牌,该令牌包含足够的信息供服务器验证未来的