我们使用BouncyCastle API为客户端加密文件。在尝试解密时,他从PGP获得了“仅供您选择”的消息。为什么?

时间:2011-05-17 19:27:49

标签: c# encryption pgp gnupg

我们使用Bouncy.Castle C#API进行PGP加密。我绝不是PGP加密专家和各种可用选项。

加密似乎运行正常,但是,当客户端尝试解密时,他说PGP不会输出到文件,只会输出到屏幕,因为它标记为“仅限你的眼睛”。这是--verbose消息:

pgp --decrypt Client_FileExport_20110510_020011.zip.pgp
  Client_FileExport_20110511_132203.zip.pgp --info verbose

McAfee E-Business Server v8.5 - Full License
(c) 1991-2006 McAfee, Inc.  All Rights Reserved.

Setting temporary directory to C:\DOCUME~1\$963\LOCALS~1\Temp\
Decoding data....

event 1: initial
event 13: BeginLex
event 8: Analyze
File is encrypted.  event 9: Recipients
Secret key is required to read it.
Key for user ID "Client_RSAv4_Key <Bob.Smith@Client.com>"
event 6: Passphrase
You need a pass phrase to unlock your secret key.

Enter pass phrase:

event 23: Decryption

symmetric cipher used: CAST5
event 11: Output options
typecode: 0062
for your eyes only


This message is marked "For your eyes only".  Display now (Y/n)?

我不清楚如何调试这个。有人知道吗?

以下是我们用于加密数据的通用代码。在这种情况下,我们不签署文档,因此可以忽略代码的一部分。

private void EncryptImpl(Stream inputStream, Stream outputStream, bool signOutput)
    {
        const int BUFFER_SIZE = 1 << 16; // should always be power of 2
        bool armor = true;
        bool withIntegrityCheck = true;

        if (armor)
            outputStream = new ArmoredOutputStream(outputStream);

        var encKey = PgpHelper.ReadPublicKey(this.EncryptionPublicKey);

        // Init encrypted data generator
        PgpEncryptedDataGenerator encryptedDataGenerator =
            new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom());
        encryptedDataGenerator.AddMethod(encKey);
        Stream encryptedOut = encryptedDataGenerator.Open(outputStream, new byte[BUFFER_SIZE]);

        // Init compression
        PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);
        Stream compressedOut = compressedDataGenerator.Open(encryptedOut);

        PgpSignatureGenerator signatureGenerator = null;
        if (signOutput)
        {
            // Init signature
            var pgpSecKey = PgpHelper.ReadSecretKey(this.OrigamiSecretKey);
            PgpPrivateKey pgpPrivKey = pgpSecKey.ExtractPrivateKey(this.PassPhrase.ToCharArray());
            signatureGenerator = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1);
            signatureGenerator.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
            foreach (string userId in pgpSecKey.PublicKey.GetUserIds())
            {
                PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();
                spGen.SetSignerUserId(false, userId);
                signatureGenerator.SetHashedSubpackets(spGen.Generate());
                // Just the first one!
                break;
            }
            signatureGenerator.GenerateOnePassVersion(false).Encode(compressedOut);
        }

        // Create the Literal Data generator output stream
        PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator();

        // TODO: Use lastwritetime from source file
        Stream literalOut = literalDataGenerator.Open(compressedOut, PgpLiteralData.Binary,
            PgpLiteralDataGenerator.Console, DateTime.Now, new byte[BUFFER_SIZE]);

        // Open the input file
        byte[] buf = new byte[BUFFER_SIZE];
        int len;
        while ((len = inputStream.Read(buf, 0, buf.Length)) > 0)
        {
            literalOut.Write(buf, 0, len);

            if (signOutput)
                signatureGenerator.Update(buf, 0, len);
        }

        literalOut.Close();
        literalDataGenerator.Close();

        if (signOutput)
            signatureGenerator.Generate().Encode(compressedOut);

        compressedOut.Close();
        compressedDataGenerator.Close();
        encryptedOut.Close();
        encryptedDataGenerator.Close();
        inputStream.Close();

        if (armor)
            outputStream.Close();
    }

2 个答案:

答案 0 :(得分:7)

我猜PgpLiteralDataGenerator.Console是导致它仅在客户端计算机的控制台中显示的原因。

Stream literalOut = literalDataGenerator.Open(
    compressedOut, 
    PgpLiteralData.Binary,             
    PgpLiteralDataGenerator.Console,
    DateTime.Now, 
    new byte[BUFFER_SIZE]);

答案 1 :(得分:2)

当加密文件不包含原始文件的名称时,会显示此消息。如果您不加密该文件,您几乎可以将任何内容放到该字段中(假设它构成一个文件名,对目标系统有效)。