无法匹配AES-GCM规范向量与Java加密库。

huangapple go评论73阅读模式
英文:

Cannot match AES-GCM specification vectors with Java Crypto library

问题

I am trying to use the Java Crypto library as a reference for another application. To make sure I was getting correct results from the library I ran some sample vectors from the AES-GCM specification to compare the results against the library results.

我正在尝试使用Java加密库作为另一个应用程序的参考。为了确保我从库中获得了正确的结果,我运行了一些来自AES-GCM规范的示例向量,以将结果与库的结果进行比较。

I am able to get the simplest vector from the specification working, but any of the more complex vectors produce results which do not match the specification.

我能够使规范中最简单的向量正常工作,但更复杂的向量产生的结果与规范不匹配。

Test case 1, which passes, uses the following code:

测试案例1通过,使用以下代码:

GCMParameterSpec parameterSpec = new GCMParameterSpec(128, stringToByteArray("0", 12));
SecretKeySpec secretKey = new SecretKeySpec(stringToByteArray("0", 16), "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
byte[] cipherText = cipher.doFinal();

Test case 2 simply adds 16B of zeros as AAD:

测试案例2简单地将16B的零添加为AAD:

GCMParameterSpec parameterSpec = new GCMParameterSpec(128, stringToByteArray("0", 12));
SecretKeySpec secretKey = new SecretKeySpec(stringToByteArray("0", 16), "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
byte[] aad = stringToByteArray("0", 16);
cipher.updateAAD(aad);
byte[] cipherText = cipher.doFinal();

This second vector and other more complicated vectors I am unable to get to match. Can someone familiar with Crypto point out where my reference code is making a mistake?

我无法使这第二个向量和其他更复杂的向量匹配。熟悉加密的人能指出我的参考代码哪里出错吗?

Full source code available here: AesGcmSampleVectors on Github

完整的源代码在这里可用:AesGcmSampleVectors on Github

Edit: The Github source code has been updated to reflect the correct output, and has added a passing example of test vector 4 from the GCM specification.

编辑:Github源代码已更新以反映正确的输出,并添加了通过的GCM规范测试向量4的示例。

英文:

I am trying to use the Java Crypto library as a reference for another application. To make sure I was getting correct results from the library I ran some sample vectors from the AES-GCM specification to compare the results against the library results.

I am able to get the simplest vector from the specification working, but any of the more complex vectors produce results which do not match the specification.

Test case 1, which passes, uses the following code:

            cipher = Cipher.getInstance("AES/GCM/NoPadding");
            GCMParameterSpec parameterSpec = new GCMParameterSpec(128, stringToByteArray("0", 12));
            SecretKeySpec secretKey = new SecretKeySpec(stringToByteArray("0", 16), "AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
            byte[] cipherText = cipher.doFinal();

Test case 2 simply adds 16B of zeros as AAD:

            cipher = Cipher.getInstance("AES/GCM/NoPadding");
            GCMParameterSpec parameterSpec = new GCMParameterSpec(128, stringToByteArray("0", 12));
            SecretKeySpec secretKey = new SecretKeySpec(stringToByteArray("0", 16), "AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
            byte[] aad = stringToByteArray("0", 16);
            cipher.updateAAD(aad);
            byte[] cipherText = cipher.doFinal();

This second vector and other more complicated vectors I am unable to get to match. Can someone familiar with Crypto point out where my reference code is making a mistake?

Full source code available here: AesGcmSampleVectors on Github

Edit: The Github source code has been updated to reflect the correct output, and has added a passing example of test vector 4 from the GCM
specification.

答案1

得分: 1

第二个测试案例没有使用AAD,但是使用了16个0x00值的明文(你似乎混淆了明文和AAD):

K  00000000000000000000000000000000
P  00000000000000000000000000000000
IV 000000000000000000000000
...
C  0388dace60b6a392f328c2b971b2fe78
T  ab6e47d42cec13bdf53a67b21257bddf

此外,需要考虑到Java将密文和标签进行拼接。以下代码实现了这一点,并成功执行:

...
byte[] expected = stringToByteArray("0388dace60b6a392f328c2b971b2fe78ab6e47d42cec13bdf53a67b21257bddf", 32); // Fix 1: Java concatenates ciphertext and Tag
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec parameterSpec = new GCMParameterSpec(128, stringToByteArray("0", 12));
SecretKeySpec secretKey = new SecretKeySpec(stringToByteArray("0", 16), "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
//byte[] aad = stringToByteArray("0", 12);      // Fix 2: No AAD specified
//cipher.updateAAD(aad);
byte[] plaintext = stringToByteArray("0", 16);  // Fix 3 specified plaintext: 16 0x00 values 
byte[] cipherText = cipher.doFinal(plaintext);  

if (Arrays.equals(cipherText, expected)) {
    System.out.println("Vectors compared OK");
} else {
    System.out.println("Vectors compared failed");
    System.out.print("Expected:");
    printByteArray(expected);
    System.out.print("Received:");
    printByteArray(cipherText);
}
...

AAD在第四个测试案例中被指定,如下所示:

K   feffe9928665731c6d6a8f9467308308
P   d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
A	feedfacedeadbeeffeedfacedeadbeefabaddad2
IV  cafebabefacedbaddecaf888
...
C   42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091
T   5bc94fbc3221a5db94fae95ae7121a47

需要按照以下方式实现(现在需要调用updateAAD()函数):

byte[] expected = stringToByteArray("42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e0915bc94fbc3221a5db94fae95ae7121a47", 76);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec parameterSpec = new GCMParameterSpec(128, stringToByteArray("cafebabefacedbaddecaf888", 12));
SecretKeySpec secretKey = new SecretKeySpec(stringToByteArray("feffe9928665731c6d6a8f9467308308", 16), "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
byte[] aad = stringToByteArray("feedfacedeadbeeffeedfacedeadbeefabaddad2", 20);
cipher.updateAAD(aad);
byte[] plaintext = stringToByteArray("d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39", 60);
byte[] cipherText = cipher.doFinal(plaintext);  

if (Arrays.equals(cipherText, expected)) {
    System.out.println("Vectors compared OK");
} else {
    System.out.println("Vectors compared failed");
    System.out.print("Expected:");
    printByteArray(expected);
    System.out.print("Received:");
    printByteArray(cipherText);
}
英文:

The second test case uses no AAD but a plaintext of 16 0x00 values (you seem to confuse plaintext and AAD):

K	00000000000000000000000000000000
P	00000000000000000000000000000000
IV	000000000000000000000000
...
C	0388dace60b6a392f328c2b971b2fe78
T 	ab6e47d42cec13bdf53a67b21257bddf

Furthermore, it must be taken into account that Java concatenates ciphertext and tag. The following code implements this correctly and is executed successfully:

...
byte[] expected = stringToByteArray("0388dace60b6a392f328c2b971b2fe78ab6e47d42cec13bdf53a67b21257bddf", 32); // Fix 1: Java concatenates ciphertext and Tag
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec parameterSpec = new GCMParameterSpec(128, stringToByteArray("0", 12));
SecretKeySpec secretKey = new SecretKeySpec(stringToByteArray("0", 16), "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
//byte[] aad = stringToByteArray("0", 12);      // Fix 2: No AAD specified
//cipher.updateAAD(aad);
byte[] plaintext = stringToByteArray("0", 16);  // Fix 3 specified plaintext: 16 0x00 values 
byte[] cipherText = cipher.doFinal(plaintext);  

if (Arrays.equals(cipherText, expected)) {
    System.out.println("Vectors compared OK");
} else {
    System.out.println("Vectors compared failed");
    System.out.print("Expected:");
    printByteArray(expected);
    System.out.print("Received:");
    printByteArray(cipherText);
}
...

AAD are specified e.g. in the fourth test case:

K   feffe9928665731c6d6a8f9467308308
P   d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
A	feedfacedeadbeeffeedfacedeadbeefabaddad2
IV  cafebabefacedbaddecaf888
...
C   42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091
T   5bc94fbc3221a5db94fae95ae7121a47

which is to be implemented as follows (now the updateAAD() call is required):

byte[] expected = stringToByteArray("42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e0915bc94fbc3221a5db94fae95ae7121a47", 76);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec parameterSpec = new GCMParameterSpec(128, stringToByteArray("cafebabefacedbaddecaf888", 12));
SecretKeySpec secretKey = new SecretKeySpec(stringToByteArray("feffe9928665731c6d6a8f9467308308", 16), "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
byte[] aad = stringToByteArray("feedfacedeadbeeffeedfacedeadbeefabaddad2", 20);
cipher.updateAAD(aad);
byte[] plaintext = stringToByteArray("d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39", 60);
byte[] cipherText = cipher.doFinal(plaintext);  

if (Arrays.equals(cipherText, expected)) {
    System.out.println("Vectors compared OK");
} else {
    System.out.println("Vectors compared failed");
    System.out.print("Expected:");
    printByteArray(expected);
    System.out.print("Received:");
    printByteArray(cipherText);
}

huangapple
  • 本文由 发表于 2023年5月26日 01:27:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76334893.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定