gpt4 book ai didi

java.io.EOFException : premature end of stream in PartialInputStream - bouncy CaSTLe

转载 作者:太空宇宙 更新时间:2023-11-04 12:09:49 25 4
gpt4 key购买 nike

在尝试解密文件时,我遇到了下面提到的异常。在这方面的任何帮助都将大有裨益。下面添加了代码以供引用。加密工作正常,解密也可以,但是当我们有大文件时,加密可以工作,但解密会出现下面提到的错误。

提前致谢

Exception in thread "Main Thread" java.io.EOFException: premature end of stream in PartialInputStream
at org.bouncycastle.bcpg.BCPGInputStream$PartialInputStream.read(Unknown Source)
at org.bouncycastle.bcpg.BCPGInputStream.read(Unknown Source)
at java.io.InputStream.read(InputStream.java:82)
at org.bouncycastle.crypto.io.CipherInputStream.nextChunk(Unknown Source)
at org.bouncycastle.crypto.io.CipherInputStream.read(Unknown Source)
at org.bouncycastle.bcpg.BCPGInputStream.read(Unknown Source)
at org.bouncycastle.openpgp.PGPEncryptedData$TruncatedStream.read(Unknown Source)
at java.io.InputStream.read(InputStream.java:151)
at org.bouncycastle.util.io.TeeInputStream.read(Unknown Source)
at org.bouncycastle.bcpg.BCPGInputStream.read(Unknown Source)
at org.bouncycastle.bcpg.BCPGInputStream$PartialInputStream.read(Unknown Source)
at org.bouncycastle.bcpg.BCPGInputStream.read(Unknown Source)
at org.bouncycastle.openpgp.PGPCompressedData$1.fill(Unknown Source)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:141)
at org.bouncycastle.bcpg.BCPGInputStream.read(Unknown Source)
at org.bouncycastle.bcpg.BCPGInputStream$PartialInputStream.read(Unknown Source)
at org.bouncycastle.bcpg.BCPGInputStream.read(Unknown Source)
at java.io.InputStream.read(InputStream.java:82)

加密/解密代码

公共(public)类 PGPUtils {

private static int BUFFER_SIZE = 1 << 24;
private static final int KEY_FLAGS = 27;
private static final int[] MASTER_KEY_CERTIFICATION_TYPES = new int[] { PGPSignature.POSITIVE_CERTIFICATION,
PGPSignature.CASUAL_CERTIFICATION, PGPSignature.NO_CERTIFICATION, PGPSignature.DEFAULT_CERTIFICATION,

};

@SuppressWarnings("unchecked")
public static PGPPublicKey readPublicKey(InputStream in) throws IOException, PGPException {

PGPPublicKeyRingCollection keyRingCollection = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(in),
new BcKeyFingerprintCalculator());

//
// we just loop through the collection till we find a key suitable for
// encryption, in the real
// world you would probably want to be a bit smarter about this.
//
PGPPublicKey publicKey = null;

//
// iterate through the key rings.
//
Iterator<PGPPublicKeyRing> rIt = keyRingCollection.getKeyRings();

while (publicKey == null && rIt.hasNext()) {
PGPPublicKeyRing kRing = rIt.next();
Iterator<PGPPublicKey> kIt = kRing.getPublicKeys();
while (publicKey == null && kIt.hasNext()) {
PGPPublicKey key = kIt.next();
if (key.isEncryptionKey()) {
publicKey = key;
}
}
}

if (publicKey == null) {
throw new IllegalArgumentException("Can't find public key in the key ring.");
}
if (!isForEncryption(publicKey)) {
throw new IllegalArgumentException("KeyID " + publicKey.getKeyID() + " not flagged for encryption.");
}
in.close();
return publicKey;
}

@SuppressWarnings("unchecked")
public static PGPSecretKey readSecretKey(InputStream in) throws IOException, PGPException {

PGPSecretKeyRingCollection keyRingCollection = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(in),
new BcKeyFingerprintCalculator());

//
// We just loop through the collection till we find a key suitable for
// signing.
// In the real world you would probably want to be a bit smarter about
// this.
//
PGPSecretKey secretKey = null;

Iterator<PGPSecretKeyRing> rIt = keyRingCollection.getKeyRings();
while (secretKey == null && rIt.hasNext()) {
PGPSecretKeyRing keyRing = rIt.next();
Iterator<PGPSecretKey> kIt = keyRing.getSecretKeys();
while (secretKey == null && kIt.hasNext()) {
PGPSecretKey key = kIt.next();
if (key.isSigningKey()) {
secretKey = key;
}
}
}

// Validate secret key
if (secretKey == null) {
throw new IllegalArgumentException("Can't find private key in the key ring.");
}
if (!secretKey.isSigningKey()) {
throw new IllegalArgumentException("Private key does not allow signing.");
}
if (secretKey.getPublicKey().isRevoked()) {
throw new IllegalArgumentException("Private key has been revoked.");
}
if (!hasKeyFlags(secretKey.getPublicKey(), KeyFlags.SIGN_DATA)) {
throw new IllegalArgumentException("Key cannot be used for signing.");
}
in.close();
return secretKey;
}

/**
* Load a secret key ring collection from keyIn and find the private key
* corresponding to keyID if it exists.
*
* @param keyIn
* input stream representing a key ring collection.
* @param keyID
* keyID we want.
* @param pass
* passphrase to decrypt secret key with.
* @return
* @throws IOException
* @throws PGPException
* @throws NoSuchProviderException
*/
public static PGPPrivateKey findPrivateKey(InputStream keyIn, long keyID, char[] pass) throws IOException,
PGPException, NoSuchProviderException {
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyIn),
new BcKeyFingerprintCalculator());
keyIn.close();
return findPrivateKey(pgpSec.getSecretKey(keyID), pass);

}

/**
* Load a secret key and find the private key in it
*
* @param pgpSecKey
* The secret key
* @param pass
* passphrase to decrypt secret key with
* @return
* @throws PGPException
*/
public static PGPPrivateKey findPrivateKey(PGPSecretKey pgpSecKey, char[] pass) throws PGPException {
if (pgpSecKey == null)
return null;

PBESecretKeyDecryptor decryptor = new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider())
.build(pass);
return pgpSecKey.extractPrivateKey(decryptor);
}

/**
* decrypt the passed in message stream
*/
@SuppressWarnings("unchecked")
public static void decryptFile(InputStream in, OutputStream out, InputStream keyIn, char[] passwd) throws Exception {
getProvider();

in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in);

PGPObjectFactory pgpF = new PGPObjectFactory(in, new BcKeyFingerprintCalculator());
PGPEncryptedDataList enc;

Object o = pgpF.nextObject();
//
// the first object might be a PGP marker packet.
//
if (o instanceof PGPEncryptedDataList) {
enc = (PGPEncryptedDataList) o;
} else {
enc = (PGPEncryptedDataList) pgpF.nextObject();
}

//
// find the secret key
//
Iterator<PGPPublicKeyEncryptedData> it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;

while (sKey == null && it.hasNext()) {
pbe = it.next();

sKey = findPrivateKey(keyIn, pbe.getKeyID(), passwd);
}

if (sKey == null) {
throw new IllegalArgumentException("Secret key for message not found.");
}

InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey));

PGPObjectFactory plainFact = new PGPObjectFactory(clear, new BcKeyFingerprintCalculator());

Object message = plainFact.nextObject();

if (message instanceof PGPCompressedData) {
PGPCompressedData cData = (PGPCompressedData) message;
PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream(), new BcKeyFingerprintCalculator());

message = pgpFact.nextObject();
}

if (message instanceof PGPLiteralData) {
PGPLiteralData ld = (PGPLiteralData) message;

InputStream unc = ld.getInputStream();
int ch;

while ((ch = unc.read()) >= 0) {
out.write(ch);
}
} else if (message instanceof PGPOnePassSignature) {
System.out.println("Instance of PGPOnePassSignature");
PGPLiteralData ld = (PGPLiteralData) message;

InputStream unc = ld.getInputStream();
int ch;

while ((ch = unc.read()) >= 0) {
out.write(ch);
}
}

else if (message instanceof PGPOnePassSignatureList) {
// throw new
// PGPException("Encrypted message contains a signed message - not literal data.");

} else {
throw new PGPException("Message is not a simple encrypted file - type unknown.");
}

if (pbe.isIntegrityProtected()) {
if (!pbe.verify()) {
throw new PGPException("Message failed integrity check");
}
}
}

/**
* decrypt the passed in signed message stream
*/
@SuppressWarnings("unchecked")
public static void decryptSignedFile(InputStream in, OutputStream out, InputStream keyIn, char[] passwd,
InputStream signPublicKeyInputStream) throws Exception {
getProvider();

in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in);

// Reading a PGP object stream
PGPObjectFactory pgpF = new PGPObjectFactory(in, new BcKeyFingerprintCalculator());

PGPEncryptedDataList enc;

Object o = pgpF.nextObject();
//
// the first object might be a PGP marker packet.
//
if (o instanceof PGPEncryptedDataList) {
enc = (PGPEncryptedDataList) o;
} else {
enc = (PGPEncryptedDataList) pgpF.nextObject();
}

//
// find the secret key
//
Iterator<PGPPublicKeyEncryptedData> it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;

while (sKey == null && it.hasNext()) {
pbe = it.next();

sKey = findPrivateKey(keyIn, pbe.getKeyID(), passwd);
}

if (sKey == null) {
throw new IllegalArgumentException("Secret key for message not found.");
}
keyIn.close();
// A decryptor factory for handling public key decryption operations
InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey));

PGPObjectFactory plainFact = new PGPObjectFactory(clear, new BcKeyFingerprintCalculator());

PGPObjectFactory objectFactory = new PGPObjectFactory(PGPUtil.getDecoderStream(in),
new BcKeyFingerprintCalculator());
Object message = plainFact.nextObject();

if (message instanceof PGPCompressedData) {
System.out.println("PGPCompressedData");

PGPCompressedData cData = (PGPCompressedData) message;
objectFactory = new PGPObjectFactory(cData.getDataStream(), new BcKeyFingerprintCalculator());

message = objectFactory.nextObject();
}

if (message instanceof PGPOnePassSignature) {
System.out.println("Instance of PGPOnePassSignature");
PGPLiteralData ld = (PGPLiteralData) message;

InputStream unc = ld.getInputStream();
int ch;

while ((ch = unc.read()) >= 0) {

out.write(ch);
}
unc.close();

}

if (message instanceof PGPOnePassSignatureList) {

PGPOnePassSignature calculatedSignature = ((PGPOnePassSignatureList) message).get(0);

PGPPublicKey signPublicKey = readPublicKey(signPublicKeyInputStream);

calculatedSignature.init(new BcPGPContentVerifierBuilderProvider(), signPublicKey);
message = objectFactory.nextObject();

} else {
throw new PGPException("Message is not a simple encrypted file - type unknown.");
}

if (message instanceof PGPLiteralData) {
PGPLiteralData ld = (PGPLiteralData) message;

InputStream uncPGLiteral = null;
try {
uncPGLiteral = ld.getDataStream();
int ch1;

byte[] buffDecrypt = new byte[PGPUtils.BUFFER_SIZE];
int len;
IOUtils.copy(uncPGLiteral, out);
// while ((len = uncPGLiteral.read(buffDecrypt)) > 0) {
// out.write(buffDecrypt, 0, len);
//
// }
} finally {
if (uncPGLiteral != null) {
System.out.println("Going to close the input stream");
uncPGLiteral.close();
out.close();

}
}

}
if (pbe.isIntegrityProtected()) {
if (!pbe.verify()) {
throw new PGPException("Message failed integrity check");
}
}
signPublicKeyInputStream.close();
clear.close();
in.close();
}

public static void encryptFile(OutputStream out, String fileName, PGPPublicKey encKey, boolean armor,
boolean withIntegrityCheck) throws IOException, NoSuchProviderException, PGPException {
getProvider();

if (armor) {
out = new ArmoredOutputStream(out);
}

ByteArrayOutputStream bOut = new ByteArrayOutputStream();
PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);

PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(fileName));

comData.close();

BcPGPDataEncryptorBuilder dataEncryptor = new BcPGPDataEncryptorBuilder(PGPEncryptedData.TRIPLE_DES);
dataEncryptor.setWithIntegrityPacket(withIntegrityCheck);
dataEncryptor.setSecureRandom(new SecureRandom());

PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(dataEncryptor);
encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(encKey));

byte[] bytes = bOut.toByteArray();
System.out.println("length is>>>>>>>" + bytes.length);
OutputStream cOut = encryptedDataGenerator.open(out, bytes.length);
cOut.write(bytes);
cOut.close();
out.close();
}

@SuppressWarnings("unchecked")
public static OutputStream signEncryptFile(String fileName, PGPPublicKey publicKey, PGPSecretKey secretKey,
String password, boolean armor, boolean withIntegrityCheck) throws Exception {
System.out.println("fileName:::" + fileName);

// Initialize Bouncy Castle security provider
getProvider();
OutputStream compressedOut = null;
try {
File inputFile = new File(fileName);

String outputFileName = fileName.concat(".pgp");
OutputStream out = new FileOutputStream(outputFileName);

if (armor) {
out = new ArmoredOutputStream(out);
}

// Bouncy Castle lightweight API to implement cryptographic
// primitives. Constructs a new data encryptor builder for a
// specified cipher type
BcPGPDataEncryptorBuilder dataEncryptor = new BcPGPDataEncryptorBuilder(PGPEncryptedData.TRIPLE_DES);
// Sets whether or not the resulting encrypted data will be
// protected using an integrity packet i.e withIntegrityPacket -
// true if an integrity packet is to be included, false otherwise
dataEncryptor.setWithIntegrityPacket(withIntegrityCheck);
dataEncryptor.setSecureRandom(new SecureRandom());

// A PGPEncryptedDataGenerator is used by configuring one or more
// encryption methods, and then invoking one of the open functions
// to create an OutputStream that raw data can be supplied to for
// encryption
PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(dataEncryptor);
// Add a key encryption method to be used to encrypt the session
// data associated with this encrypted data
encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey));

// Create an OutputStream based on the configured methods to write a
// single encrypted object of known length
OutputStream encryptedOut = encryptedDataGenerator.open(out, new byte[BUFFER_SIZE]);

// Generator for producing compressed data packets. Initialize
// compressed data generator
PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(
PGPCompressedData.UNCOMPRESSED);
compressedOut = compressedDataGenerator.open(encryptedOut);

// Initialize signature generator
PGPPrivateKey privateKey = findPrivateKey(secretKey, password.toCharArray());

// Initialize Content Sign Builder parameters are {int keyAlgorithm,
// int hashAlgorithm}
PGPContentSignerBuilder signerBuilder = new BcPGPContentSignerBuilder(secretKey.getPublicKey()
.getAlgorithm(), HashAlgorithmTags.SHA1);

// Create a signature generator built on the passed in
// contentSignerBuilder
PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(signerBuilder);
// Initialise the generator for signing
signatureGenerator.init(PGPSignature.STAND_ALONE, privateKey);

boolean firstTime = true;
Iterator<String> it = secretKey.getPublicKey().getUserIDs();
while (it.hasNext() && firstTime) {
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
spGen.setSignerUserID(false, it.next());
signatureGenerator.setHashedSubpackets(spGen.generate());
// Exit the loop after the first iteration
firstTime = false;
}
signatureGenerator.generateOnePassVersion(false).encode(compressedOut);

// Generator for producing literal data packets.A
// PGPLiteralDataGenerator is usually used to wrap the OutputStream
// obtained from a PGPEncryptedDataGenerator or a
// PGPCompressedDataGenerator. Initialize literal data generator
PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator();
OutputStream literalOut = literalDataGenerator.open(compressedOut, PGPLiteralData.UTF8, fileName,
inputFile.length(), new Date());

// Main loop - read the "in" stream, compress, encrypt and write to
// the
// "out" stream
InputStream in = new FileInputStream(fileName);
byte[] buf = new byte[BUFFER_SIZE];
int len;
while ((len = in.read(buf)) > 0) {
literalOut.write(buf, 0, len);
signatureGenerator.update(buf, 0, len);
}

in.close();
literalOut.close();
literalDataGenerator.close();
// Generate the signature, compress, encrypt and write to the "out"
// stream

signatureGenerator.generate();

compressedOut.close();
compressedDataGenerator.close();
encryptedOut.close();
encryptedDataGenerator.close();

if (armor) {
out.close();
}
} catch (Exception e) {
System.out.println("Error is::" + e.getMessage());
}

return compressedOut;
}

public static boolean verifyFile(InputStream in, InputStream keyIn, String extractContentFile) throws Exception {
in = PGPUtil.getDecoderStream(in);

PGPObjectFactory pgpFact = new PGPObjectFactory(in, new BcKeyFingerprintCalculator());
PGPCompressedData c1 = (PGPCompressedData) pgpFact.nextObject();

pgpFact = new PGPObjectFactory(c1.getDataStream(), new BcKeyFingerprintCalculator());

PGPOnePassSignatureList p1 = (PGPOnePassSignatureList) pgpFact.nextObject();

PGPOnePassSignature ops = p1.get(0);

PGPLiteralData p2 = (PGPLiteralData) pgpFact.nextObject();

InputStream dIn = p2.getInputStream();

IOUtils.copy(dIn, new FileOutputStream(extractContentFile));

int ch;
PGPPublicKeyRingCollection pgpRing = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(keyIn),
new BcKeyFingerprintCalculator());

PGPPublicKey key = pgpRing.getPublicKey(ops.getKeyID());

FileOutputStream out = new FileOutputStream(p2.getFileName());

ops.init(new BcPGPContentVerifierBuilderProvider(), key);

while ((ch = dIn.read()) >= 0) {
ops.update((byte) ch);
out.write(ch);
}

out.close();

PGPSignatureList p3 = (PGPSignatureList) pgpFact.nextObject();
return ops.verify(p3.get(0));
}

/**
* From LockBox Lobs PGP Encryption tools.
* http://www.lockboxlabs.org/content/downloads
*
* I didn't think it was worth having to import a 4meg lib for three methods
*
* @param key
* @return
*/
public static boolean isForEncryption(PGPPublicKey key) {
if (key.getAlgorithm() == PublicKeyAlgorithmTags.RSA_SIGN || key.getAlgorithm() == PublicKeyAlgorithmTags.DSA
|| key.getAlgorithm() == PublicKeyAlgorithmTags.EC
|| key.getAlgorithm() == PublicKeyAlgorithmTags.ECDSA) {
return false;
}

return hasKeyFlags(key, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE);
}

/**
* From LockBox Lobs PGP Encryption tools.
* http://www.lockboxlabs.org/content/downloads
*
* I didn't think it was worth having to import a 4meg lib for three methods
*
* @param key
* @return
*/
@SuppressWarnings("unchecked")
private static boolean hasKeyFlags(PGPPublicKey encKey, int keyUsage) {
System.out.println("In hasKeyFlags+" + encKey.isMasterKey());
if (encKey.isMasterKey()) {
System.out.println("In Here" + PGPUtils.MASTER_KEY_CERTIFICATION_TYPES.length);
for (int i = 0; i != PGPUtils.MASTER_KEY_CERTIFICATION_TYPES.length; i++) {
for (Iterator<PGPSignature> eIt = encKey
.getSignaturesOfType(PGPUtils.MASTER_KEY_CERTIFICATION_TYPES[i]); eIt.hasNext();) {
PGPSignature sig = eIt.next();
if (!isMatchingUsage(sig, keyUsage)) {
return false;
}
}
}
} else {
for (Iterator<PGPSignature> eIt = encKey.getSignaturesOfType(PGPSignature.SUBKEY_BINDING); eIt.hasNext();) {
PGPSignature sig = eIt.next();
if (!isMatchingUsage(sig, keyUsage)) {
return false;
}
}
}
return true;
}

/**
* From LockBox Lobs PGP Encryption tools.
* http://www.lockboxlabs.org/content/downloads
*
* I didn't think it was worth having to import a 4meg lib for three methods
*
* @param key
* @return
*/
private static boolean isMatchingUsage(PGPSignature sig, int keyUsage) {
System.out.println("isMatchingUsage::");
if (sig.hasSubpackets()) {
PGPSignatureSubpacketVector sv = sig.getHashedSubPackets();
if (sv.hasSubpacket(PGPUtils.KEY_FLAGS)) {
// code fix suggested by kzt (see comments)
if ((sv.getKeyFlags() == 0) && (keyUsage == 0)) {
return false;
}
}
}
return true;
}

private static Provider getProvider() {
Provider provider = Security.getProvider("BC");
if (provider == null) {
provider = new BouncyCastleProvider();
Security.addProvider(provider);
}
return provider;
}

}

最佳答案

代码太复杂,不够完整,无法真正测试。但是,我确实注意到 signEncryptFile 中流关闭的顺序看起来错误。如果您在签名和加密操作期间生成错误数据,那么您的 decryptSignedFile 方法可能会失败。

signEncryptFile 中看起来错误的特定序列是:

signatureGenerator.generate();
compressedDataGenerator.close();
encryptedDataGenerator.close();
compressedOut.close();
encryptedOut.close();

特别请注意,您在执行 compressedOut.close(); 之前先执行 encryptedDataGenerator.close();。这意味着压缩缓冲区中的数据没有机会写入后续流,因为您已经关闭了它。

我预计这种情况会导致 compressedOut.close 抛出异常,但我不确定。

我建议您非常仔细重新检查此流关闭,以确保它完全按照您的预期进行。

关于java.io.EOFException : premature end of stream in PartialInputStream - bouncy CaSTLe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39954023/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com