Я использую этот метод для шифрования и подписи сообщения с помощью ключа PGP для проверки и дешифрования.
public static String encryptAndSignPGPMessage(String message, PGPPublicKey publicKey, PGPPrivateKey signingKey) throws Exception {
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
ArmoredOutputStream armoredOutputStream = new ArmoredOutputStream(byteOutputStream);
// Create an encrypted data generator
PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256)
.setWithIntegrityPacket(true)
.setSecureRandom(new SecureRandom())
.setProvider("BC"));
// Add public key encryption method
encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(publicKey)
.setSecureRandom(new SecureRandom())
.setProvider("BC"));
// Start encryption
OutputStream encryptedOutputStream = encGen.open(armoredOutputStream, new byte[4096]);
// Initialize the signature generator
PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(
new JcaPGPContentSignerBuilder(signingKey.getPublicKeyPacket().getAlgorithm(), PGPUtil.SHA256)
.setProvider("BC"));
// Initiate the signing process
signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, signingKey);
// Create a one-pass signature before the literal data
PGPOnePassSignature onePassSignature = signatureGenerator.generateOnePassVersion(false);
// Write the one-pass signature to the encrypted output
onePassSignature.encode(encryptedOutputStream);
// Write the encrypted message to the stream
byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8);
encryptedOutputStream.write(messageBytes);
encryptedOutputStream.close();
// Generate the signature and write it to the armored output
signatureGenerator.generate().encode(armoredOutputStream);
armoredOutputStream.close();
return byteOutputStream.toString(StandardCharsets.UTF_8.name());
}
public static String decryptAndVerifyPGPMessage(String pgpMessage, PGPPrivateKey privateKey, PGPPublicKey publicKey) throws Exception {
// Ensure the PGP message is formatted correctly
ByteArrayInputStream inputStream = new ByteArrayInputStream(pgpMessage.getBytes(StandardCharsets.UTF_8));
InputStream decodedInputStream = PGPUtil.getDecoderStream(inputStream);
// Create PGPObjectFactory for reading the decoded stream
PGPObjectFactory pgpFactory = new JcaPGPObjectFactory(decodedInputStream);
Object object = pgpFactory.nextObject();
// Expecting an EncryptedDataList
PGPEncryptedDataList encryptedDataList;
// Check if the first object is an encrypted data list
if (object instanceof PGPEncryptedDataList) {
encryptedDataList = (PGPEncryptedDataList) object;
} else {
// If the first object is not a PGPEncryptedDataList, try the next one
object = pgpFactory.nextObject();
if (object instanceof PGPEncryptedDataList) {
encryptedDataList = (PGPEncryptedDataList) object;
} else {
throw new PGPException("No encrypted data found in the PGP message.");
}
}
// Iterate through the encrypted data list
for (Object encData : encryptedDataList) {
if (encData instanceof PGPPublicKeyEncryptedData) {
PGPPublicKeyEncryptedData publicKeyEncryptedData = (PGPPublicKeyEncryptedData) encData;
// Decrypt the data
InputStream clearInput = publicKeyEncryptedData.getDataStream(
new JcePublicKeyDataDecryptorFactoryBuilder()
.setProvider("BC")
.build(privateKey));
PGPObjectFactory clearFactory = new JcaPGPObjectFactory(clearInput);
// Read the one-pass signature
PGPOnePassSignatureList onePassSignatureList = (PGPOnePassSignatureList) clearFactory.nextObject();
PGPOnePassSignature onePassSignature = onePassSignatureList.get(0);
// Read the signed literal data
PGPLiteralData literalData = (PGPLiteralData) clearFactory.nextObject();
InputStream literalInput = literalData.getInputStream();
// Prepare to read the decrypted message
StringBuilder decryptedMessage = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(literalInput));
String line;
// Initialize the one-pass signature for verification
onePassSignature.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey);
// Update the signature with the message content
while ((line = reader.readLine()) != null) {
decryptedMessage.append(line).append("\n");
onePassSignature.update(line.getBytes(StandardCharsets.UTF_8));
}
// Read and verify the signature
PGPSignatureList signatureList = (PGPSignatureList) clearFactory.nextObject();
PGPSignature pgpSignature = signatureList.get(0);
// Verify the signature
boolean isSignatureValid = onePassSignature.verify(pgpSignature);
System.out.println("Signature valid: " + isSignatureValid);
if (isSignatureValid) {
return decryptedMessage.toString().trim(); // Return decrypted message if signature is valid
} else {
throw new PGPException("Signature verification failed.");
}
}
}
throw new PGPException("No valid encrypted data found.");
}
После шифрования я успешно получил сообщение, зашифрованное PGP, но при попытке его расшифровать.
Я обнаружил ошибку:java.io.IOException: invalid header encountered at this line "PGPLiteralData literalData = (PGPLiteralData) clearFactory.nextObject();"
Подробнее здесь: https://stackoverflow.com/questions/790 ... cryption-a
Шифрование PGP и подписание однопроходного сообщения не удалось расшифровать и проверить. ⇐ JAVA
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Я хочу зашифровать и расшифровать AES-GCM на языке C#, но не могу расшифровать
Anonymous » » в форуме C# - 0 Ответы
- 43 Просмотры
-
Последнее сообщение Anonymous
-