PgpPbeEncryptedData
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.IO;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System;
using System.IO;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
public class PgpPbeEncryptedData : PgpEncryptedData
{
private readonly SymmetricKeyEncSessionPacket m_keyData;
internal PgpPbeEncryptedData(SymmetricKeyEncSessionPacket keyData, InputStreamPacket encData)
: base(encData)
{
m_keyData = keyData;
}
public Stream GetDataStream(char[] passPhrase)
{
byte[] rawPassPhrase = PgpUtilities.EncodePassPhrase(passPhrase, false);
return ImplGetDataStream(rawPassPhrase, true);
}
public Stream GetDataStreamUtf8(char[] passPhrase)
{
byte[] rawPassPhrase = PgpUtilities.EncodePassPhrase(passPhrase, true);
return ImplGetDataStream(rawPassPhrase, true);
}
public Stream GetDataStreamRaw(byte[] rawPassPhrase)
{
return ImplGetDataStream(rawPassPhrase, false);
}
internal Stream ImplGetDataStream(byte[] rawPassPhrase, bool clearPassPhrase)
{
try {
SymmetricKeyAlgorithmTag algorithm = m_keyData.EncAlgorithm;
KeyParameter parameters = PgpUtilities.DoMakeKeyFromPassPhrase(algorithm, m_keyData.S2k, rawPassPhrase, clearPassPhrase);
byte[] secKeyData = m_keyData.GetSecKeyData();
if (secKeyData != null && secKeyData.Length != 0) {
IBufferedCipher cipher = CipherUtilities.GetCipher(PgpUtilities.GetSymmetricCipherName(algorithm) + "/CFB/NoPadding");
cipher.Init(false, new ParametersWithIV(parameters, new byte[cipher.GetBlockSize()]));
byte[] array = cipher.DoFinal(secKeyData);
algorithm = (SymmetricKeyAlgorithmTag)array[0];
parameters = ParameterUtilities.CreateKeyParameter(PgpUtilities.GetSymmetricCipherName(algorithm), array, 1, array.Length - 1);
}
string symmetricCipherName = PgpUtilities.GetSymmetricCipherName(algorithm);
IBufferedCipher bufferedCipher = CreateBufferedCipher(symmetricCipherName);
bufferedCipher.Init(false, new ParametersWithIV(parameters, new byte[bufferedCipher.GetBlockSize()]));
Stream stream = InitDecStream(new CipherStream(GetInputStream(), bufferedCipher, null));
PgpEncryptedData.QuickCheck(StreamUtilities.RequireBytes(stream, bufferedCipher.GetBlockSize() + 2));
return stream;
} catch (PgpException) {
throw;
} catch (Exception innerException) {
throw new PgpException("Exception creating cipher", innerException);
}
}
}
}