PGP (Pretty Good Privacy) — это зашифрованный протокол связи, используемый для защиты безопасности и конфиденциальности электронной почты и файлов. Он обеспечивает конфиденциальность, целостность и проверяемость данных за счет использования технологий шифрования, цифровых подписей и сжатия.
Первоначально GP была разработана Ником Эмбрейсом и Эриком Хьюзом в Массачусетском технологическом институте, а затем доработана Филом Циммерманном. Он использует механизм шифрования с открытым ключом и расшифровки с закрытым ключом, чтобы гарантировать, что только получатель сообщения может расшифровать и прочитать содержимое сообщения.
Основные преимущества PGP заключаются в простоте использования и интеграции с большинством популярных почтовых клиентов. Однако с появлением более совершенных технологий и стандартов шифрования (таких как OpenPGP и GPG), PGP был в некоторой степени заменен этими новыми стандартами.
PGP предназначен не только для электронной почты, его также можно использовать для шифрования файлов и данных.
В целом, PGP — это надежный протокол шифрования, используемый для защиты конфиденциальности и целостности коммуникаций, обеспечивая при этом механизм аутентификации. Он широко используется для шифрования электронной почты и файлов, чтобы обеспечить безопасность и конфиденциальность данных пользователей.
OpenPGP и GPG (GNU Privacy Guard) — это открытые стандарты и бесплатные программные реализации PGP (Pretty Good Privacy). Со временем стандарты и реализации PGP постепенно развивались, причем OpenPGP и GPG стали двумя важными разработками.
OpenPGP — это открытый стандарт, определяющий протокол шифрования и цифровой подписи данных. Этот стандарт обеспечивает совместимость различного криптографического программного обеспечения друг с другом, а это означает, что пользователи, использующие различные реализации OpenPGP, могут безопасно обмениваться зашифрованной информацией. Стандарт OpenPGP определен в RFC 4880 и включает в себя методы генерации, обмена и проверки открытых и закрытых ключей, а также алгоритмы шифрования и подписи.
GPG — это популярная реализация OpenPGP, которая является частью проекта GNU и выпущена под лицензией GNU General Public License (GPL). GPG — это инструмент командной строки, который работает в различных операционных системах, включая Linux, macOS и Windows. GPG предоставляет возможность создавать и проверять цифровые подписи, шифровать файлы и электронные письма, а также безопасно обмениваться ключами.
Основные компоненты GPG включают в себя:
Сценарии использования GPG включают:
PGP (Pretty Good Privacy) включает в себя такие ключевые этапы, как шифрование, цифровые подписи и управление ключами.
В целом, ПГПиз Принцип работыс участиемшифрование、цифровая подпись Управление ключами, конфиденциальность сообщения гарантируется этими шагами.、Полнота и проверяемость.
По сути, PGP имеет три основных использования:
Предположим, Алиса и Боб — два пользователя, общающиеся с использованием шифрования PGP. Им нужна безопасная связь по электронной почте, чтобы защитить конфиденциальность и целостность их сообщений.
В этом случае Алиса и Боб используют протокол PGP для шифрования и дешифрования связи между ними, а также могут использоваться цифровые подписи для обеспечения целостности сообщения и проверки личности отправителя. Таким образом, они могут безопасно обмениваться информацией, не опасаясь, что она будет украдена или подделана неавторизованными третьими лицами.
Полная реализация протокола PGP в Java требует использования сторонних библиотек, поскольку PGP — это сложный протокол шифрования. Одной из часто используемых библиотек является Bouncy Castle.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.artisan</groupId>
<artifactId>pgp-encryption</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpg-jdk15on</artifactId>
<version>1.70</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.70</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
</project>
package com.artisan.pgpUtils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import org.apache.commons.io.IOUtils;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.CompressionAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Objects;
/**
* @author artisan
*/
@Getter
@Builder
@AllArgsConstructor
public class PgpEncryptionUtil {
/**
* Уилл Надувной Замок добавлен в JVM
*/
static {
// Уилл Надувной Замок добавлен в JVM
if (Objects.isNull(Security.getProvider(BouncyCastleProvider.PROVIDER_NAME))) {
Security.addProvider(new BouncyCastleProvider());
}
}
/**
* Алгоритм сжатия, по умолчанию ZIP.
*/
@Builder.Default
private int compressionAlgorithm = CompressionAlgorithmTags.ZIP;
/**
* Алгоритм симметричного ключа, по умолчанию AES-128.
*/
@Builder.Default
private int symmetricKeyAlgorithm = SymmetricKeyAlgorithmTags.AES_128;
/**
* Включить ли ASCII Броня, по умолчанию верно
*/
@Builder.Default
private boolean armor = true;
/**
* Включить ли проверку целостности, по умолчанию — true.
*/
@Builder.Default
private boolean withIntegrityCheck = true;
/**
* Размер буфера, по умолчанию — 65536 байт.
*/
@Builder.Default
private int bufferSize = 1 << 16;
/**
* шифрованиеметод,чистый текстданныеиспользоватьоткрытый ключруководитьшифрование *
* @param encryptOut
* @param clearIn
* @param length
* @param publicKeyIn
* @throws IOException
* @throws PGPException
*/
public void encrypt(OutputStream encryptOut, InputStream clearIn, long length, InputStream publicKeyIn)
throws IOException, PGPException {
// Создать генератор сжатых данных
PGPCompressedDataGenerator compressedDataGenerator =
new PGPCompressedDataGenerator(compressionAlgorithm);
// Создать шифрованный генератор PGP
PGPEncryptedDataGenerator pgpEncryptedDataGenerator = new PGPEncryptedDataGenerator(
// Конфигурацияшифрованиеданныегенерировать器 new JcePGPDataEncryptorBuilder(symmetricKeyAlgorithm)
.setWithIntegrityPacket(withIntegrityCheck)
.setSecureRandom(new SecureRandom())
.setProvider(BouncyCastleProvider.PROVIDER_NAME)
);
// 添加открытый ключ
pgpEncryptedDataGenerator.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(
CommonUtils.getPublicKey(publicKeyIn)));
// еслидавать возможностьASCII Броня, создайте ArmoredOutputStream.
if (armor) {
encryptOut = new ArmoredOutputStream(encryptOut);
}
// Выходной поток открытого шифрования
OutputStream cipherOutStream = pgpEncryptedDataGenerator.open(encryptOut, new byte[bufferSize]);
// Включите генератор сжатых данных и преобразуйте данные в виде обычного текста в выходной поток шифрования в буквальной форме копировать.
CommonUtils.copyAsLiteralData(compressedDataGenerator.open(cipherOutStream), clearIn, length, bufferSize);
// Последовательно закрыть все выходные потоки
compressedDataGenerator.close();
cipherOutStream.close();
encryptOut.close();
}
/**
* метод шифрования, возвращает байты после шифрования множества
*
* @param clearData
* @param pubicKeyIn
* @return
* @throws PGPException
* @throws IOException
*/
public byte[] encrypt(byte[] clearData, InputStream pubicKeyIn) throws PGPException, IOException {
ByteArrayInputStream inputStream = new ByteArrayInputStream(clearData);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
encrypt(outputStream, inputStream, clearData.length, pubicKeyIn);
return outputStream.toByteArray();
}
// метод шифрования, возвращает входной поток после шифрования
public InputStream encrypt(InputStream clearIn, long length, InputStream publicKeyIn)
throws IOException, PGPException {
File tempFile = File.createTempFile("pgp-", "-encrypted");
encrypt(Files.newOutputStream(tempFile.toPath()), clearIn, length, publicKeyIn);
return Files.newInputStream(tempFile.toPath());
}
/**
* шифрованиеметод,чистый текстданныеиспользоватьоткрытый ключString шифрование
*
* @param clearData
* @param publicKeyStr
* @return
* @throws PGPException
* @throws IOException
*/
public byte[] encrypt(byte[] clearData, String publicKeyStr) throws PGPException, IOException {
return encrypt(clearData, IOUtils.toInputStream(publicKeyStr, Charset.defaultCharset()));
}
/**
* метод шифрования, возвращает входной поток после шифрования
*
* @param clearIn
* @param length
* @param publicKeyStr
* @return
* @throws IOException
* @throws PGPException
*/
public InputStream encrypt(InputStream clearIn, long length, String publicKeyStr) throws IOException, PGPException {
return encrypt(clearIn, length, IOUtils.toInputStream(publicKeyStr, Charset.defaultCharset()));
}
}
package com.artisan.pgpUtils;
import org.apache.commons.io.IOUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataList;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.security.Security;
import java.util.Iterator;
import java.util.Objects;
/**
* @author artisan
*/
public class PgpDecryptionUtil {
static {
// Уилл Надувной Замок добавлен в JVM
if (Objects.isNull(Security.getProvider(BouncyCastleProvider.PROVIDER_NAME))) {
Security.addProvider(new BouncyCastleProvider());
}
}
/**
* закрытый ключ Пароль
*/
private final char[] passCode;
/**
* коллекция брелоков
*/
private final PGPSecretKeyRingCollection pgpSecretKeyRingCollection;
/**
* @param privateKeyIn
* @param passCode
* @throws IOException
* @throws PGPException
*/
public PgpDecryptionUtil(InputStream privateKeyIn, String passCode) throws IOException, PGPException {
this.passCode = passCode.toCharArray(); // Преобразование пароля в несколько символов
// Чтение коллекции PGP из входного потока брелоков
this.pgpSecretKeyRingCollection = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(privateKeyIn)
, new JcaKeyFingerprintCalculator());
}
/**
* @param privateKeyStr
* @param passCode
* @throws IOException
* @throws PGPException
*/
public PgpDecryptionUtil(String privateKeyStr, String passCode) throws IOException, PGPException {
// Волязакрытый ключ Преобразовать строку во входной поток
this(IOUtils.toInputStream(privateKeyStr, Charset.defaultCharset()), passCode);
}
/**
* Найти закрытый по указанному идентификатору ключ
*
* @param keyID
* @return
* @throws PGPException
*/
private PGPPrivateKey findSecretKey(long keyID) throws PGPException {
// Получите закрытие с указанным идентификатором из брелока. ключ
PGPSecretKey pgpSecretKey = pgpSecretKeyRingCollection.getSecretKey(keyID);
// использоватьпароль Расшифроватьзакрытый ключ
return pgpSecretKey == null ? null : pgpSecretKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder()
.setProvider(BouncyCastleProvider.PROVIDER_NAME).build(passCode));
}
/**
* Метод дешифрования, расшифровывает входной поток шифрования в выходной поток открытого текста.
*
* @param encryptedIn
* @param clearOut
* @throws PGPException
* @throws IOException
*/
public void decrypt(InputStream encryptedIn, OutputStream clearOut)
throws PGPException, IOException {
// Удалить ASCII Armor и возвращает базовый поток двоичного шифрования.
encryptedIn = PGPUtil.getDecoderStream(encryptedIn);
JcaPGPObjectFactory pgpObjectFactory = new JcaPGPObjectFactory(encryptedIn);
Object obj = pgpObjectFactory.nextObject();
// Первым объектом может быть пакет с тегом data.
PGPEncryptedDataList pgpEncryptedDataList = (obj instanceof PGPEncryptedDataList)
? (PGPEncryptedDataList) obj : (PGPEncryptedDataList) pgpObjectFactory.nextObject();
PGPPrivateKey pgpPrivateKey = null;
PGPPublicKeyEncryptedData publicKeyEncryptedData = null;
Iterator<PGPEncryptedData> encryptedDataItr = pgpEncryptedDataList.getEncryptedDataObjects();
while (pgpPrivateKey == null && encryptedDataItr.hasNext()) {
publicKeyEncryptedData = (PGPPublicKeyEncryptedData) encryptedDataItr.next();
pgpPrivateKey = findSecretKey(publicKeyEncryptedData.getKeyID()); // Находитьзакрытый ключ
}
if (Objects.isNull(publicKeyEncryptedData)) {
throw new PGPException("Невозможно создать объект PGPPublicKeyEncryptedData");
}
if (pgpPrivateKey == null) {
throw new PGPException("Невозможно извлечь закрытый ключ");
}
CommonUtils.decrypt(clearOut, pgpPrivateKey, publicKeyEncryptedData); // Вызов универсального метода расшифровки
}
/**
* Метод расшифровки: расшифровать множество байтов шифрования в несколько байтов открытого текста.
*
* @param encryptedBytes
* @return
* @throws PGPException
* @throws IOException
*/
public byte[] decrypt(byte[] encryptedBytes) throws PGPException, IOException {
ByteArrayInputStream encryptedIn = new ByteArrayInputStream(encryptedBytes);
ByteArrayOutputStream clearOut = new ByteArrayOutputStream();
// Метод расшифровки вызова
decrypt(encryptedIn, clearOut);
// Вернуть расшифрованное целое число открытого текста (множество)
return clearOut.toByteArray();
}
}
package com.artisan.pgpUtils;
import org.apache.commons.io.IOUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
import org.bouncycastle.openpgp.PGPOnePassSignatureList;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Date;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Optional;
/**
* @author artisan
*/
public class CommonUtils {
/**
* использовать提供иззакрытый ключ Расшифроватьоткрытый ключшифрованные и записать его в выходной поток
*
* @param clearOut Выходной поток для записи в данные
* @param pgpPrivateKey закрытый ключ Пример
* @param publicKeyEncryptedData открытый Примеры ключей шифрования
* @throws IOException Ошибки, связанные с вводом-выводом
* @throws PGPException Ошибки, связанные с PGP
*/
static void decrypt(OutputStream clearOut, PGPPrivateKey pgpPrivateKey, PGPPublicKeyEncryptedData publicKeyEncryptedData) throws IOException, PGPException {
PublicKeyDataDecryptorFactory decryptorFactory = new JcePublicKeyDataDecryptorFactoryBuilder()
.setProvider(BouncyCastleProvider.PROVIDER_NAME).build(pgpPrivateKey);
InputStream decryptedCompressedIn = publicKeyEncryptedData.getDataStream(decryptorFactory);
JcaPGPObjectFactory decCompObjFac = new JcaPGPObjectFactory(decryptedCompressedIn);
PGPCompressedData pgpCompressedData = (PGPCompressedData) decCompObjFac.nextObject();
InputStream compressedDataStream = new BufferedInputStream(pgpCompressedData.getDataStream());
JcaPGPObjectFactory pgpCompObjFac = new JcaPGPObjectFactory(compressedDataStream);
Object message = pgpCompObjFac.nextObject();
if (message instanceof PGPLiteralData) {
PGPLiteralData pgpLiteralData = (PGPLiteralData) message;
InputStream decDataStream = pgpLiteralData.getInputStream();
IOUtils.copy(decDataStream, clearOut);
clearOut.close();
} else if (message instanceof PGPOnePassSignatureList) {
throw new PGPException("Сообщение шифрования содержит подписанное сообщение вместо текстовых данных");
} else {
throw new PGPException("Сообщение не является простым шифрованием файла. - Неизвестный тип");
}
// Выполнить проверку целостности
if (publicKeyEncryptedData.isIntegrityProtected()) {
if (!publicKeyEncryptedData.verify()) {
throw new PGPException("Проверка целостности сообщения не удалась");
}
}
}
/**
* Преобразование данныхкопирование из входного потока в литеральные данные pgp и запись в предоставленный выходной поток.
*
* @param outputStream Выходной поток, в который следует писать
* @param in Чтобы прочитать входной поток данных
* @param length длина данных для чтения
* @param bufferSize Размер буфера, поскольку использование буфера ускоряет копирование.
* @throws IOException Ошибки, связанные с вводом-выводом
*/
static void copyAsLiteralData(OutputStream outputStream, InputStream in, long length, int bufferSize) throws IOException {
PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
OutputStream pOut = lData.open(outputStream, PGPLiteralData.BINARY, PGPLiteralData.CONSOLE,
Date.from(LocalDateTime.now().toInstant(ZoneOffset.UTC)), new byte[bufferSize]);
byte[] buff = new byte[bufferSize];
try {
int len;
long totalBytesWritten = 0L;
while (totalBytesWritten <= length && (len = in.read(buff)) > 0) {
pOut.write(buff, 0, len);
totalBytesWritten += len;
}
pOut.close();
} finally {
// очистить буфер
Arrays.fill(buff, (byte) 0);
// Закрыть входной поток
in.close();
}
}
/**
* Получить открытый ключевой входной поток ключ
*
* @param keyInputStream ключевой входной поток
* @return Экземпляр PGPPublicKey
* @throws IOException Ошибки, связанные с вводом-выводом
* @throws PGPException Ошибки, связанные с PGP
*/
static PGPPublicKey getPublicKey(InputStream keyInputStream) throws IOException, PGPException {
PGPPublicKeyRingCollection pgpPublicKeyRings = new PGPPublicKeyRingCollection(
PGPUtil.getDecoderStream(keyInputStream), new JcaKeyFingerprintCalculator());
Iterator<PGPPublicKeyRing> keyRingIterator = pgpPublicKeyRings.getKeyRings();
while (keyRingIterator.hasNext()) {
PGPPublicKeyRing pgpPublicKeyRing = keyRingIterator.next();
Optional<PGPPublicKey> pgpPublicKey = extractPGPKeyFromRing(pgpPublicKeyRing);
if (pgpPublicKey.isPresent()) {
return pgpPublicKey.get();
}
}
throw new PGPException("Недопустимый открытый ключ");
}
private static Optional<PGPPublicKey> extractPGPKeyFromRing(PGPPublicKeyRing pgpPublicKeyRing) {
for (PGPPublicKey publicKey : pgpPublicKeyRing) {
if (publicKey.isEncryptionKey()) {
return Optional.of(publicKey);
}
}
return Optional.empty();
}
}
package com.artisan.pgpUtils;
import org.apache.commons.io.IOUtils;
import org.bouncycastle.bcpg.CompressionAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.openpgp.PGPException;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.Optional;
import static org.junit.Assert.assertEquals;
public class PgpEncryptionTest {
public static final TemporaryFolder tempFolder = new TemporaryFolder();
private PgpEncryptionUtil pgpEncryptionUtil = null;
private PgpDecryptionUtil pgpDecryptionUtil = null;
/**
* Вспомогательный метод для загрузки файлов ресурсов
* @param resourcePath
* @return
*/
private static URL loadResource(String resourcePath) {
return Optional.ofNullable(PgpEncryptionTest.class.getResource(resourcePath))
.orElseThrow(() -> new IllegalArgumentException("Resource not found"));
}
private static final String passkey = "dummy";
private final URL privateKey = loadResource("/private.pgp");
private final URL publicKey = loadResource("/public.pgp");
private final URL testFile = loadResource("/Sample_CSV_5300kb.csv");
private static final String testString = "This text needs to be PGP encrypted";
/**
* Создайте временную папку перед запуском тестового класса.
* @throws IOException
*/
@BeforeClass
public static void construct() throws IOException {
tempFolder.delete();
tempFolder.create();
}
/**
* Очистить временную папку после запуска тестового класса
*/
@AfterClass
public static void destroy() {
tempFolder.delete();
}
/**
* Метод инициализации, выполняемый перед запуском каждого метода тестирования.
*/
@Before
public void init() {
// Класс инструмента инициализации шифрования
pgpEncryptionUtil = PgpEncryptionUtil.builder()
.armor(true)
.compressionAlgorithm(CompressionAlgorithmTags.ZIP)
.symmetricKeyAlgorithm(SymmetricKeyAlgorithmTags.AES_128)
.withIntegrityCheck(true)
.build();
try {
// Инициализировать класс инструмента дешифрования
pgpDecryptionUtil = new PgpDecryptionUtil(privateKey.openStream(),ключ доступа);
} catch (IOException | PGPException e) {
выдать новые исключения RuntimeException;
}
}
/**
* тест байт-множествошифрование
* @выбрасывает исключение IOException
* @throws PGPException
*/
@Тест
public void testByteEncryption() выдает IOException,PGPException {
// шифрованиетестбайтмножество byte[] encryptedBytes = pgpEncryptionUtil.encrypt(testString.getBytes(Charset.defaultCharset()),
publicKey.openStream());
// Расшифруйте сгенерированное шифрование в большом количестве байтов.
byte[] decryptedBytes = pgpDecryptionUtil.decrypt(encryptedBytes);
// Преобразуйте множество расшифрованных байтов в строку и сравните с исходной тестовой строкой.
assertEquals(testString, new String(decryptedBytes,Charset.defaultCharset()));
}
/**
*документшифрование
* @выбрасывает исключение IOException
* @throws URISyntaxException
* @throws PGPException
*/
@Тест
public void testFileEncryption() выдает IOException, URISyntaxException, PGPException {
// Создайте временный файл шифрования PGP, созданный на основе тестового файла.
File encryptedFile = tempFolder.newFile();
File originalFile = new File(testFile.toURI());
try (OutputStream fos = Files.newOutputStream(encryptedFile.toPath())) {
pgpEncryptionUtil.encrypt(fos, Files.newInputStream(originalFile.toPath()), originalFile.length(),
publicKey.openStream());
}
// Расшифруйте сгенерированный временный файл шифрования PGP и запишите его в другой временный файл.
File decryptedFile = tempFolder.newFile();
pgpDecryptionUtil.decrypt(Files.newInputStream(encryptedFile.toPath()), Files.newOutputStream(decryptedFile.toPath()));
// Сравните исходное содержимое файла с расшифрованным содержимым файла.
assertEquals(IOUtils.toString(Files.newInputStream(originalFile.toPath()), Charset.defaultCharset()),
IOUtils.toString(Files.newInputStream(decryptedFile.toPath()),Charset.defaultCharset()));
}
/**
*Входной поток шифрование
* @выбрасывает исключение IOException
* @throws URISyntaxException
* @throws PGPException
*/
@Тест
public void testInputStreamEncryption() выдает IOException, URISyntaxException, PGPException {
// Создайте входной поток шифрования PGP, созданный из тестового файла.
File originalFile = new File(testFile.toURI());
InputStream encryptedIn = pgpEncryptionUtil.encrypt(Files.newInputStream(originalFile.toPath()), originalFile.length(), publicKey.openStream());
// Расшифруйте сгенерированный входной поток и запишите его во временный файл.
File decryptedFile = tempFolder.newFile();
pgpDecryptionUtil.decrypt(encryptedIn, Files.newOutputStream(decryptedFile.toPath()));
// Сравните исходное содержимое файла с расшифрованным содержимым файла.
assertEquals(IOUtils.toString(Files.newInputStream(originalFile.toPath()), Charset.defaultCharset()),
IOUtils.toString(Files.newInputStream(decryptedFile.toPath()),Charset.defaultCharset()));
}
/**
* использовать新Конфигурациятестбайтмножествошифрование * @throws IOException
* @throws PGPException
*/
@Test
public void testByteEncryptionWithNewConf() throws IOException,PGPException {
pgpEncryptionUtil = PgpEncryptionUtil.builder()
.armor(ложь)
.compressionAlgorithm(CompressionAlgorithmTags.BZIP2)
.symmetricKeyAlgorithm(SymmetricKeyAlgorithmTags.BLOWFISH)
.withIntegrityCheck(ложь)
.строить();
// тест на шифрование множество
byte[] EncryptionBytes = pgpEncryptionUtil.encrypt(testString.getBytes(Charset.defaultCharset()),
publicKey.openStream());
// Расшифруйте сгенерированное шифрование в большом количестве байтов.
byte[] decryptedBytes = pgpDecryptionUtil.decrypt(encryptedBytes);
// Преобразуйте множество расшифрованных байтов в строку и сравните с исходной тестовой строкой.
assertEquals(testString, new String(decryptedBytes, Charset.defaultCharset()));
}
}
Когда мы отправляем электронные письма или файлы через Интернет, мы хотим, чтобы их содержимое оставалось конфиденциальным, и мы хотим подтвердить личность отправителя и целостность данных. Именно это и делает PGP (Pretty Good Privacy).
Представьте, что у вас есть ключ. Этот ключ состоит из двух частей: одна — открытый ключ, а другая — закрытый ключ.
Если вы хотите отправить кому-то личное сообщение, вы используете его открытое сообщение. ключ к шифрованию новостей. Только тогда они смогут использовать свой собственный закрытый двор. ключ Приходить Расшифровать сообщение. Таким образом, даже если кто-то перехватит сообщение во время передачи, он не сможет его прочитать, поскольку у него нет закрытого доступа. ключ。
Кроме того, PGP также можно использовать для цифровых подписей. Как и подпись в письме, цифровая подпись подтверждает личность отправителя и целостность сообщения. Отправитель использует свой закрытый ключ для подписи сообщения, а получатель использует открытый ключ отправителя для проверки подписи, чтобы гарантировать, что сообщение не было подделано и отправлено отправителем.
Подводя итог, можно сказать, что PGP — это технология шифрования, используемая для защиты электронной почты и файлов с помощью открытых и закрытых ключей для шифрования и дешифрования сообщений, а также с помощью цифровых подписей для проверки происхождения и целостности сообщения.