use*_*492 2 java encryption 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();
}
Run Code Online (Sandbox Code Playgroud)
是的,可以在没有认证标签的情况下解密消息:如果您阅读GCM规范,您可以看到CTR的IV仅仅是IV,附加了四个字节00000002(即计数器从零开始,增加1用于计算身份验证标记,再次为加密计数器的起始值).
所以这是代码,inc我用它来验证我的计数器代码两次; 当然可以简单地将最后一个字节设置为值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;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:此代码用于无效标记或无法重新计算的标记(例如,可能缺少AAD).删除- TAG_SIZE / Byte.SIZE从doFinal在标签被完全丢失.
| 归档时间: |
|
| 查看次数: |
789 次 |
| 最近记录: |