Я убедился, что ключ AES и IV отображаются правильно, но проверка MAC не удалась. Обычно это происходит, когда данные или связанный тег изменены или неверны.
Исследование:
Я использую GCMParameterSpec для IV и длину тега 128 бит. для дешифрования AES.
Эта ошибка предполагает несоответствие между зашифрованным текстом и тегом аутентификации, что может указывать на проблему с IV, ключом AES или целостностью данных во время шифрования/дешифрования.
Код: Выделить всё
public class Encryption {
static String certificatePath =
"C:\\\\Users\\\\PSAD07564\\\\Desktop\\\\Peppol\\\\IVLenght\\\\peppol."
+ "lx.erf01.net.crt";
private static final String RSA_TRANSFORMATION =
"RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
private static final String AES_TRANSFORMATION = "AES/GCM/NoPadding";
private static final int GCM_TAG_LENGTH = 128;
// static String privateKey = "D:\\Mahipalsing\\POC
// CERT\\PROD\\NEW_SAN\\uxplpiacp01.lx.erf01.net_GUI.key";
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
// Path to the .key file
String keyFilePath =
"C:\\Users\\PSAD07564\\Desktop\\Peppol\\IVLenght\\peppol.lx.erf01."
+ "net.key";
// Read the private key file
String keyContent =
new String(Files.readAllBytes(Paths.get(keyFilePath)));
// Remove PEM headers and clean up the content
keyContent = keyContent.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s+", ""); // Remove all whitespace
// Debugging: Print the cleaned-up key content
// System.out.println("Cleaned Key Content: " + keyContent);
// Decode the Base64-encoded private key
byte[] keyBytes = Base64.getDecoder().decode(keyContent);
// Generate a PrivateKey instance
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory =
KeyFactory.getInstance("RSA"); // Use the appropriate algorithm
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
String plainText = "AES 256 GCM Testing";
// Create a CertificateFactory instance
CertificateFactory certificateFactory =
CertificateFactory.getInstance("X.509");
// Read the certificate from the file
FileInputStream fis = new FileInputStream(certificatePath);
X509Certificate certificate =
(X509Certificate) certificateFactory.generateCertificate(fis);
CMSEnvelopedDataGenerator cmsEnvelopedDataGenerator =
new CMSEnvelopedDataGenerator();
CMSEnvelopedData data = null;
cmsEnvelopedDataGenerator.addRecipientInfoGenerator(
new JceKeyTransRecipientInfoGenerator(
certificate, rsaesOaepIdentifier())
.setProvider(BouncyCastleProvider.PROVIDER_NAME));
data = cmsEnvelopedDataGenerator.generate(
new CMSProcessableByteArray(plainText.getBytes()),
new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_GCM)
.setProvider("BC")
.build());
byte[] data1 = data.getEncoded();
System.out.println("Data:");
System.out.println(data);
System.out.println(data1);
CMSEnvelopedDataParser cmsEnvelopedDataParser =
new CMSEnvelopedDataParser(data1);
Collection recipients =
cmsEnvelopedDataParser.getRecipientInfos().getRecipients();
Iterator it =
(Iterator) recipients.iterator();
RecipientInformation recipient = it.next();
InputStream decryptedStream =
recipient
.getContentStream(
new JceKeyTransEnvelopedRecipient(privateKey)
.setAlgorithmMapping(
PKCSObjectIdentifiers.id_RSAES_OAEP,
"RSA/GCM/OAEPWithSHA-256AndMGF1Padding"))
.getContentStream();
System.out.println(
"decryptedStream : " + convertInputstreamToString(decryptedStream));
ContentInfo info =
ContentInfo.getInstance(ASN1Primitive.fromByteArray(data1));
EnvelopedData envData = EnvelopedData.getInstance(info.getContent());
ASN1Set s = envData.getRecipientInfos();
RecipientInfo recipientInfo =
RecipientInfo.getInstance(s.getObjectAt(0));
byte[] encryptedKey;
if (recipientInfo.getInfo() instanceof KeyTransRecipientInfo) {
KeyTransRecipientInfo keyTransRecipientInfo =
KeyTransRecipientInfo.getInstance(recipientInfo.getInfo());
encryptedKey = keyTransRecipientInfo.getEncryptedKey().getOctets();
AlgorithmIdentifier keyEncryptionAlgorithm =
keyTransRecipientInfo.getKeyEncryptionAlgorithm();
System.out.println(keyEncryptionAlgorithm.getAlgorithm().getId());
System.out.println(encryptedKey);
System.out.println("Encrypted Key Length: " + encryptedKey.length);
// Decrypt the AES key using the private key
OAEPParameterSpec oaepSpec = new OAEPParameterSpec("SHA-256",
"MGF1", new MGF1ParameterSpec("SHA-256"),
PSource.PSpecified.DEFAULT);
Cipher rsaCipher = Cipher.getInstance(
RSA_TRANSFORMATION, BouncyCastleProvider.PROVIDER_NAME);
System.out.println("Step: 1");
rsaCipher.init(Cipher.DECRYPT_MODE, privateKey, oaepSpec);
System.out.println("Step: 2");
System.out.println(
"rsaCipher Blocksize: " + rsaCipher.getBlockSize());
byte[] aesKeyBytes = rsaCipher.doFinal(encryptedKey);
System.out.println(aesKeyBytes);
System.out.println("aesKeyBytes Key Length: " + aesKeyBytes.length);
// Reconstruct the AES key
AlgorithmIdentifier contentEncryptionAlgorithm =
envData.getEncryptedContentInfo()
.getContentEncryptionAlgorithm();
System.out.println("Symmetric Encryption Algorithm : "
+ contentEncryptionAlgorithm.getAlgorithm().getId());
System.out.println("Octect Encrypted data : "
+ Hex.toHexString(envData.getEncryptedContentInfo()
.getEncryptedContent()
.getOctets()));
SecretKey aesKey = new SecretKeySpec(aesKeyBytes, "AES");
System.out.println("Step: 3");
// Process the AES decryption as needed...
Cipher aesCipher = Cipher.getInstance(
AES_TRANSFORMATION, BouncyCastleProvider.PROVIDER_NAME);
System.out.println("Step: 4");
byte[] iv = new byte[16];
ASN1Primitive iv1 = envData.getEncryptedContentInfo()
.getContentEncryptionAlgorithm()
.getParameters()
.toASN1Primitive();
System.out.println(iv1);
SecureRandom randomGenerator = new SecureRandom();
randomGenerator.nextBytes(iv);
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, iv);
System.out.println("Step: 5");
aesCipher.init(Cipher.DECRYPT_MODE, aesKey, gcmSpec);
System.out.println("Step: 6");
byte[] FinalContain =
aesCipher.doFinal(envData.getEncryptedContentInfo()
.getEncryptedContent()
.getOctets());
System.out.println("Step: 7");
System.out.println("FinalContain: ");
System.out.println(FinalContain);
} else {
throw new IllegalStateException("expected KeyTransRecipientInfo");
}
AlgorithmIdentifier contentEncryptionAlgorithm =
envData.getEncryptedContentInfo().getContentEncryptionAlgorithm();
System.out.println("Symmetric Encryption Algorithm : "
+ contentEncryptionAlgorithm.getAlgorithm().getId());
System.out.println("Octect Encrypted data : "
+ Hex.toHexString(envData.getEncryptedContentInfo()
.getEncryptedContent()
.getOctets()));
}
private static String convertInputstreamToString(
InputStream decryptedStream) throws IOException {
try (BufferedReader reader =
new BufferedReader(new InputStreamReader(decryptedStream))) {
return reader.lines().collect(
Collectors.joining(System.lineSeparator()));
}
}
private static AlgorithmIdentifier rsaesOaepIdentifier() {
// TODO Auto-generated method stub
AlgorithmIdentifier hash = new AlgorithmIdentifier(
NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE);
AlgorithmIdentifier mask =
new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hash);
AlgorithmIdentifier pSource =
new AlgorithmIdentifier(PKCSObjectIdentifiers.id_pSpecified,
new DEROctetString(new byte[0]));
return new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSAES_OAEP,
new RSAESOAEPparams(hash, mask, pSource));
}
}
Код: Выделить всё
Data:
org.bouncycastle.cms.CMSEnvelopedData@368247b9
[B@1a6d8329
decryptedStream : AES 256 GCM Testing
1.2.840.113549.1.1.7
[B@710c2b53
Encrypted Key Length: 256
Step: 1
Step: 2
rsaCipher Blocksize: 256
[B@5386659f
aesKeyBytes Key Length: 32
Symmetric Encryption Algorithm : 2.16.840.1.101.3.4.1.46
Octect Encrypted data : 4b72ef2cc6624f297d701ab38627f73ac8a72fb50ed9d615f0616815d757b89bf8aeac
Step: 3
Step: 4
[#461ab7477bacd84583cc743d, 16]
Step: 5
Step: 6
Код: Выделить всё
Exception in thread "main" javax.crypto.AEADBadTagException: mac check in GCM failed
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Unknown Source)
at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$AEADGenericBlockCipher.doFinal(Unknown Source)
at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)
at java.base/javax.crypto.Cipher.doFinal(Unknown Source)
at peppoltest.demo.Encryption.main(Encryption.java:197)
Что может быть причиной этого исключения AEADBadTagException в режиме GCM и как его устранить? Должен ли я проверить IV или параметры шифрования, или проблема связана с чем-то другим в процессе расшифровки?
Подробнее здесь: https://stackoverflow.com/questions/792 ... h-bouncyca
Мобильная версия