/// <summary> /// Helper for getting encryption stream /// </summary> /// <param name="stream">Stream to chain for encryption</param> /// <param name="input">Task settings</param> /// <returns>Encryption chained stream</returns> internal static Stream GetEncryptionStream(Stream stream, PgpEncryptInput input) { SymmetricKeyAlgorithmTag algorithmTag = input.EncryptionAlgorithm.ConvertEnum <SymmetricKeyAlgorithmTag>(); PgpPublicKey publicKey = ReadPublicKey(input.PublicKeyFile); PgpEncryptedDataGenerator encryptedDataGenerator = new PgpEncryptedDataGenerator(algorithmTag, input.UseIntegrityCheck, new SecureRandom()); encryptedDataGenerator.AddMethod(publicKey); return(encryptedDataGenerator.Open(stream, new byte[PgpTasks.EncryptBufferSize])); }
/// <summary> /// Gets compression stream if compression is needed, otherwise returns original stream /// </summary> /// <param name="stream">Source stream</param> /// <param name="input">Task input</param> /// <returns>Compression chained stream or original source</returns> internal static Stream GetCompressionStream(Stream stream, PgpEncryptInput input) { if (input.UseArmor) { CompressionAlgorithmTag compressionTag = input.CompressionType.ConvertEnum <CompressionAlgorithmTag>(); PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(compressionTag); return(compressedDataGenerator.Open(stream)); } return(stream); }
/// <summary> /// Encrypts a file using public key. /// If needed, the file can also be signed with private key, in this case, the order is sign and encrypt. /// See https://github.com/CommunityHiQ/Frends.Community.PgpEncryptFile /// </summary> /// <param name="input">Task input</param> /// <returns>Returns: Object {string FilePath}</returns> public static PgpEncryptResult EncryptFile(PgpEncryptInput input) { // source file to encrypt var inputFile = new FileInfo(input.InputFile); if (!inputFile.Exists) { throw new ArgumentException("File to encrypt does not exists", input.InputFile); } // destination file using (Stream outputStream = File.OpenWrite(input.OutputFile)) // ascii output? using (var armoredStream = input.UseArmor ? new ArmoredOutputStream(outputStream) : outputStream) using (var encryptedOut = PgpServices.GetEncryptionStream(armoredStream, input)) using (var compressedOut = PgpServices.GetCompressionStream(encryptedOut, input)) { // signature init - if necessary var signatureGenerator = input.SignWithPrivateKey ? PgpServices.InitPgpSignatureGenerator(compressedOut, input) : null; // writing to configured output var literalDataGenerator = new PgpLiteralDataGenerator(); var file = new FileInfo(input.InputFile); using (var literalOut = literalDataGenerator.Open(compressedOut, PgpLiteralData.Binary, file.Name, file.Length, DateTime.Now)) using (var inputStream = inputFile.OpenRead()) { var buf = new byte[EncryptBufferSize]; int len; while ((len = inputStream.Read(buf, 0, buf.Length)) > 0) { literalOut.Write(buf, 0, len); if (input.SignWithPrivateKey) { signatureGenerator.Update(buf, 0, len); } } if (input.SignWithPrivateKey) { signatureGenerator.Generate().Encode(compressedOut); } } } return(new PgpEncryptResult { FilePath = input.OutputFile }); }
/// <summary> /// Helper for creating a PgpSignatureGenerator from private key file and its password /// </summary> /// <param name="stream">Stream to use for signature initialization</param> /// <param name="input">Encryption task input</param> /// <returns>PgpSignatureGenerator to be used when signing a file</returns> internal static PgpSignatureGenerator InitPgpSignatureGenerator(Stream stream, PgpEncryptInput input) { HashAlgorithmTag hashAlgorithm = input.SigningSettings.SignatureHashAlgorithm.ConvertEnum <HashAlgorithmTag>(); try { PgpSecretKey secretKey = ReadSecretKey(input.SigningSettings.PrivateKeyFile); PgpPrivateKey privateKey = secretKey.ExtractPrivateKey(input.SigningSettings.PrivateKeyPassword.ToCharArray()); var pgpSignatureGenerator = new PgpSignatureGenerator(secretKey.PublicKey.Algorithm, hashAlgorithm); pgpSignatureGenerator.InitSign(PgpSignature.BinaryDocument, privateKey); foreach (string userId in secretKey.PublicKey.GetUserIds()) { PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator(); spGen.SetSignerUserId(false, userId); pgpSignatureGenerator.SetHashedSubpackets(spGen.Generate()); // Just the first one! break; } pgpSignatureGenerator.GenerateOnePassVersion(false).Encode(stream); return(pgpSignatureGenerator); } catch (PgpException e) { throw new Exception("Private key extraction failed, password might be incorrect", e); } }