问题描述
|
我正在尝试解密刚使用bouncycastle加密的文件,但是我收到了此异常:
Premature end of stream in PartialInputStream
我使用的是bouncycastle的示例代码,并且没有进行任何更改。
使用以下代码进行加密时,我得到了这个:
private static byte[] EncryptFile(byte[] clearData,string fileName,PgpPublicKey encKey,bool withIntegrityCheck)
{
MemoryStream encOut = new MemoryStream();
try
{
MemoryStream bOut = new MemoryStream();
PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator( CompressionAlgorithmTag.Zip );
//PgpUtilities.WriteFiletoLiteralData(
// comData.Open(bOut),// PgpLiteralData.Binary,// new FileInfo(fileName));
Stream cos = comData.Open(bOut);
PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator();
Stream pOut = lData.Open(
cos,PgpLiteralData.Binary,fileName,clearData.Length,DateTime.UtcNow
);
lData.Close();
comData.Close();
PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator( SymmetricKeyAlgorithmTag.Cast5,withIntegrityCheck,new SecureRandom() );
cPk.AddMethod(encKey);
byte[] bytes = bOut.ToArray();
Stream os = encOut;
Stream cOut = cPk.Open(os,bytes.Length);
cOut.Write(bytes,bytes.Length);
cOut.Close();
encOut.Close();
}
catch (PgpException e)
{
Console.Error.WriteLine(e);
Exception underlyingException = e.InnerException;
if (underlyingException != null)
{
Console.Error.WriteLine(underlyingException.Message);
Console.Error.WriteLine(underlyingException.StackTrace);
}
}
return encOut.ToArray();
}
我认为这与PgpLiteralDataGenerator
有关。
但是我需要使用它,因为我想从字节数组而不是文件中加密数据。还有其他方法吗?
解决方法
任何在这里苦苦挣扎的人都是有效的代码:
using System;
using System.Xml;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Text;
using Org.BouncyCastle.Bcpg.OpenPgp;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.IO;
using Org.BouncyCastle.Utilities.Encoders;
using Org.BouncyCastle.Bcpg;
class Program
{
private static PgpPublicKey ReadPublicKey(Stream inputStream)
{
inputStream = PgpUtilities.GetDecoderStream(inputStream);
PgpPublicKeyRingBundle pgpPub = new PgpPublicKeyRingBundle(inputStream);
//
// 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.
//
//
// iterate through the key rings.
//
foreach (PgpPublicKeyRing kRing in pgpPub.GetKeyRings())
{
foreach (PgpPublicKey k in kRing.GetPublicKeys())
{
if (k.IsEncryptionKey)
{
return k;
}
}
}
throw new ArgumentException(\"Can\'t find encryption key in key ring.\");
}
private static byte[] EncryptFile(byte[] clearData,string fileName,PgpPublicKey encKey,bool withIntegrityCheck)
{
MemoryStream bOut = new MemoryStream();
PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator(
CompressionAlgorithmTag.Zip);
Stream cos = comData.Open(bOut); // open it with the final destination
PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator();
// we want to Generate compressed data. This might be a user option later,// in which case we would pass in bOut.
Stream pOut = lData.Open(
cos,// the compressed output stream
PgpLiteralData.Binary,fileName,// \"filename\" to store
clearData.Length,// length of clear data
DateTime.UtcNow // current time
);
pOut.Write(clearData,clearData.Length);
lData.Close();
comData.Close();
PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5,new SecureRandom());
cPk.AddMethod(encKey);
byte[] bytes = bOut.ToArray();
MemoryStream encOut = new MemoryStream();
Stream os = encOut;
Stream cOut = cPk.Open(os,bytes.Length);
cOut.Write(bytes,bytes.Length); // obtain the actual bytes from the compressed stream
cOut.Close();
encOut.Close();
return encOut.ToArray();
}
static void Main(string[] args)
{
try
{
byte[] dataBytes = File.ReadAllBytes(\"test.xml\");
Stream keyIn = File.OpenRead(\"cert.asc\");
Stream outStream = File.Create(\"data.bpg\");
byte[] encrypted = EncryptFile(dataBytes,\"data\",ReadPublicKey(keyIn),false);
outStream.Write(encrypted,encrypted.Length);
keyIn.Close();
outStream.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadLine();
}
}
,当我尝试从\'stream \'中读取内容时,出现了相同的错误。
PgpLiteralData ld = (PgpLiteralData)message;
var stream = ld.GetInputStream(); // the stream to read form
我的解决方案是将流复制到新的.net Stream对象
像MemoryStream
。然后从memoryStream对象读取。
因此,我的基本流类型与Org.BouncyCastle.Bcpg
流类型无关。