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

我有一些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。

以上是 JAVA中的AES GCM解密绕过身份验证 的全部内容, 来源链接: utcz.com/qa/397655.html

回到顶部