我们使用 BouncyCastle API 为客户端加密文件。他得到了“仅限您的眼睛”的字样。尝试解密时来自 PGP 的消息。为什么?
我们使用 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 <[email protected]>"
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();
}
We use the Bouncy.Castle C# API to do PGP encryption. I am by no means an expert on PGP encryption and the various options available.
The encryption seems to run fine, however, when the client tries to decrypt it, he says that PGP won't output to file but only output to screen because it is marked "For your eyes only." This is the --verbose message:
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 <[email protected]>"
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)?
I have no clue as to how to go about debugging this. Anybody know?
Here is the general code we use to encrypt data. In this scenario we are not signing the document, so that portion of the code can be ignored.
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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我猜测是 PgpLiteralDataGenerator.Console 导致它仅显示在客户端计算机的控制台中。
I'm guessing that PgpLiteralDataGenerator.Console is what is causing it to show up only in the console of the client machine.
当加密文件不包含原始文件的名称时,会显示此消息。如果您不加密文件,则可以将几乎任何内容放入该字段(假定它构成文件名,对目标系统有效)。
This message is shown when the encrypted file doesn't include a name of the original file. If you are not encrypting the file, you can put almost anything to that field (given that it constitutes a file name, valid for the target system).