0

BouncyCastle を使用して PGPEncryption でファイルを暗号化しようとしています。暗号化されたデータを AsciiArmored にフォーマットすると、復号化も正常に機能します。

しかし、AsciiArmored を無効にすると、約 12kb のファイル [暗号化された形式] が生成されます。同じコードで同じものを復号化しようとしましたが、現在、以下のエラーがスローされています

java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(Unknown Source)
at java.io.BufferedInputStream.available(Unknown Source)
at org.bouncycastle.openpgp.PGPUtil$BufferedInputStreamExt.available(Unknown Source)
at org.bouncycastle.bcpg.BCPGInputStream.available(Unknown Source)
at org.bouncycastle.bcpg.BCPGInputStream$PartialInputStream.available(Unknown Source)
at org.bouncycastle.bcpg.BCPGInputStream.available(Unknown Source)
at java.io.FilterInputStream.available(Unknown Source)
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(Unknown Source)
at org.bouncycastle.util.io.TeeInputStream.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(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 sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)

テスト クラス:

public void testDecrypt() throws Exception {
        this.pgpFileProcessor.setPassphrase(PASSPHRASE);
        this.pgpFileProcessor.setSecretKeyFileName(PRI_KEY_FILE);
        this.pgpFileProcessor.setAsciiArmored(false);

        this.pgpFileProcessor.setInputFileName(OUTPUT);
        this.pgpFileProcessor.setOutputFileName(TEMP_SG);
        InputStream is = this.pgpFileProcessor.decryptToStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));

        StringBuilder sb = new StringBuilder();

        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line + "\n");
        }

        System.out.println(sb.toString());

        br.close();
        is.close();
    }

ユーティリティ クラス

public InputStream decryptToStream() throws Exception {
    FileInputStream in = new FileInputStream(this.inputFileName);
    FileInputStream keyIn = new FileInputStream(this.secretKeyFileName);
    InputStream inputStream = this.pgpUtils.decryptFile(in, keyIn, this.passphrase.toCharArray());
    in.close();
    keyIn.close();
    return inputStream;
}

実際のコード:

public InputStream decryptFile(InputStream in, InputStream keyIn, char[] passwd) throws Exception {
    InputStream decryptedData = null;

    Security.addProvider(new BouncyCastleProvider());
    in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in);
    PGPObjectFactory pgpF = new PGPObjectFactory(in);
    PGPEncryptedDataList enc;

    Object o = pgpF.nextObject();
    if (o instanceof PGPEncryptedDataList) {
        enc = (PGPEncryptedDataList) o;
    } else {
        enc = (PGPEncryptedDataList) pgpF.nextObject();
    }

    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) {
        in.close();
        throw new IllegalArgumentException("Secret key for message not found.");
    }
    if (pbe == null) {
        in.close();
        throw new IllegalArgumentException("Encrypted Data is Malformed");
    }

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

    PGPObjectFactory plainFact = new PGPObjectFactory(clear);

    Object message = plainFact.nextObject();

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

        message = pgpFact.nextObject();
    }

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

        decryptedData = ld.getInputStream();
        /*
         * int ch; while ((ch = unc.read()) >= 0) { out.write(ch); }
         */

    } else if (message instanceof PGPOnePassSignatureList) {
        in.close();
        clear.close();
        throw new PGPException("Encrypted message contains a signed message - not literal data.");
    } else {
        in.close();
        clear.close();
        throw new PGPException("Message is not a simple encrypted file - type unknown.");
    }
    if (pbe.isIntegrityProtected()) {
        if (!pbe.verify()) {
            in.close();
            clear.close();
            throw new PGPException("Message failed integrity check");
        }
    }
    clear.close();
    in.close();
    return decryptedData;
}
4

1 に答える 1

3

の最後の行でストリームを閉じていますdecryptFile():

in.close();
return decryptedData;

そこでストリームを閉じないでください。一般的なルールは次のとおりです。ストリームを開いたのと同じメソッドでストリームを閉じます。パターンは次のようになります。

InputStream in = null;
try {
    in = ...
    // use the stream here.
} finally {
    if (in != null) {
        in.close();
    }
}

または、Java 7 を使用している場合:

try (
    InputStream in = ...; // initialize stream here

) {
    // use the stream here.
}

初期化されたストリームを閉じる必要はありませんtry ()。自動で閉まります。Java 7 をお楽しみください。

于 2013-01-28T10:15:16.227 に答える