Hier ist meine aktuelle Implementierung eines einen Pass Hüpfburg PGP encrypt + Zeichen. Die Signatur scheint zu verifizieren, aber die Nutzlast wird nicht entschlüsselt.
public class SinglePassSignedEncryptedFileProcessor {
private static final Logger logger = LoggerFactory.getLogger(SinglePassSignedEncryptedFileProcessor.class);
/*
* This is the primary function that will create encrypt a file and sign it
* with a one pass signature. This leans on an C# example by John Opincar
* @author Bilal Soylu
* @param targetFileName
* -- file name on drive systems that will contain encrypted content
* @param embeddedFileName
* -- the original file name before encryption
* @param secretKeyRingInputStream
* -- Private Key Ring File
* @param targetFileStream
* -- The stream for the encrypted target file
* @param secretKeyPassphrase
* -- The private key password for the key retrieved from
* collection used for signing
* @param signPublicKeyInputStream
* -- the public key of the target recipient to be used to
* encrypt the file
* @throws Exception
*/
public void encryptOnePassSign(
String fileName,
InputStream keyIn,
OutputStream out,
char[] pass,
PGPPublicKey encryptionKey,
boolean armor,
boolean withIntegrityCheck,
String providerName)
throws IOException, NoSuchAlgorithmException, NoSuchProviderException, PGPException, SignatureException {
if (armor) {
out = new ArmoredOutputStream(out);
}
// Compress
byte[] bytes = PGPEncryptUtil.compressFile(fileName, CompressionAlgorithmTags.ZIP);
// Encryption process.
PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC"));
encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encryptionKey).setProvider("BC"));
ByteArrayOutputStream encryptedOutputStream = new ByteArrayOutputStream();
OutputStream encryptedOut = encGen.open(encryptedOutputStream, bytes);
encryptedOut.write(bytes);
encryptedOut.close();
byte[] bytesEncrypted = encryptedOutputStream.toByteArray();
encryptedOutputStream.close();
// Signing process.
PGPSecretKey pgpSec = PGPEncryptUtil.readSecretKey(keyIn);
PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));
PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1).setProvider("BC"));
sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
Iterator it = pgpSec.getPublicKey().getUserIDs();
if (it.hasNext()) {
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
spGen.setSignerUserID(false, (String) it.next());
sGen.setHashedSubpackets(spGen.generate());
}
PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
PGPCompressedData.UNCOMPRESSED);
// Write to the output stream.
BCPGOutputStream bOut = new BCPGOutputStream(cGen.open(out));
sGen.generateOnePassVersion(false).encode(bOut);
File file = new File(fileName);
PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
// file is encoding name.
Date lastModified = new Date(file.lastModified());
OutputStream lOut = lGen.open(bOut, PGPLiteralData.BINARY, fileName, lastModified, bytesEncrypted);
//FileInputStream fIn = new FileInputStream(file);
//int ch;
//while ((ch = fIn.read()) >= 0) {
lOut.write(bytesEncrypted);
sGen.update(bytesEncrypted);
// }
// ?
lGen.close();
sGen.generate().encode(bOut);
cGen.close();
if (armor) {
out.close();
}
// close everything down we are done
/*
literalOut.close();
literalDataGenerator.close();
signatureGenerator.generate().encode(compressedOut);
compressedOut.close();
compressedDataGenerator.close();
encryptedOut.close();
encryptedDataGenerator.close();
*/
// if (armor) targetFileStream.close();
}
}
Es gibt drei Methoden von MACing: Authentifizieren Dann verschlüsseln, Authentifizierung und Verschlüsselung (was es scheint, Sie wollen) und Verschlüsseln Dann Authentifizieren. Die Sicherheit ist nicht für alle drei gleich. Moxies Standpunkt ist, dass man vor der Authentifizierung bei der Entschlüsselung so wenig wie möglich tun sollte. In der Tat ist eine Schwachstelle in TLS AES/CBC, dass es nicht verschlüsselt ist, dann Mac. Die Wahl wirkt sich auf die Sicherheit aus. Siehe [The Cryptographic Doom Principle] (https://moxie.org/blog/the-cryptographic-doom-principle/) – zaph