<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.0" />

PgpPbeEncryptedData

using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.IO; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities.IO; using System; using System.IO; namespace Org.BouncyCastle.Bcpg.OpenPgp { public class PgpPbeEncryptedData : PgpEncryptedData { private readonly SymmetricKeyEncSessionPacket keyData; internal PgpPbeEncryptedData(SymmetricKeyEncSessionPacket keyData, InputStreamPacket encData) : base(encData) { this.keyData = keyData; } public override Stream GetInputStream() { return encData.GetInputStream(); } public Stream GetDataStream(char[] passPhrase) { return DoGetDataStream(PgpUtilities.EncodePassPhrase(passPhrase, false), true); } public Stream GetDataStreamUtf8(char[] passPhrase) { return DoGetDataStream(PgpUtilities.EncodePassPhrase(passPhrase, true), true); } public Stream GetDataStreamRaw(byte[] rawPassPhrase) { return DoGetDataStream(rawPassPhrase, false); } internal Stream DoGetDataStream(byte[] rawPassPhrase, bool clearPassPhrase) { try { SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = keyData.EncAlgorithm; KeyParameter parameters = PgpUtilities.DoMakeKeyFromPassPhrase(symmetricKeyAlgorithmTag, keyData.S2k, rawPassPhrase, clearPassPhrase); byte[] secKeyData = keyData.GetSecKeyData(); if (secKeyData != null && secKeyData.Length != 0) { IBufferedCipher cipher = CipherUtilities.GetCipher(PgpUtilities.GetSymmetricCipherName(symmetricKeyAlgorithmTag) + "/CFB/NoPadding"); cipher.Init(false, new ParametersWithIV(parameters, new byte[cipher.GetBlockSize()])); byte[] array = cipher.DoFinal(secKeyData); symmetricKeyAlgorithmTag = (SymmetricKeyAlgorithmTag)array[0]; parameters = ParameterUtilities.CreateKeyParameter(PgpUtilities.GetSymmetricCipherName(symmetricKeyAlgorithmTag), array, 1, array.Length - 1); } IBufferedCipher bufferedCipher = CreateStreamCipher(symmetricKeyAlgorithmTag); byte[] array2 = new byte[bufferedCipher.GetBlockSize()]; bufferedCipher.Init(false, new ParametersWithIV(parameters, array2)); encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), bufferedCipher, null)); if (encData is SymmetricEncIntegrityPacket) { truncStream = new TruncatedStream(encStream); IDigest readDigest = PgpUtilities.CreateDigest(HashAlgorithmTag.Sha1); encStream = new DigestStream(truncStream, readDigest, null); } if (Streams.ReadFully(encStream, array2, 0, array2.Length) < array2.Length) throw new EndOfStreamException("unexpected end of stream."); int num = encStream.ReadByte(); int num2 = encStream.ReadByte(); if (num < 0 || num2 < 0) throw new EndOfStreamException("unexpected end of stream."); bool num3 = array2[array2.Length - 2] == (byte)num && array2[array2.Length - 1] == (byte)num2; bool flag = num == 0 && num2 == 0; if (!num3 && !flag) throw new PgpDataValidationException("quick check failed."); return encStream; } catch (PgpException) { throw; } catch (Exception innerException) { throw new PgpException("Exception creating cipher", innerException); } } private IBufferedCipher CreateStreamCipher(SymmetricKeyAlgorithmTag keyAlgorithm) { string str = (encData is SymmetricEncIntegrityPacket) ? "CFB" : "OpenPGPCFB"; return CipherUtilities.GetCipher(PgpUtilities.GetSymmetricCipherName(keyAlgorithm) + "/" + str + "/NoPadding"); } } }