You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用C#实现双证书文件加密(对应指定OpenSSL命令)

Replicating OpenSSL S/MIME Encryption with Two Certificates in C#

Hey there! Let's break down how to match the behavior of your OpenSSL command in C#. The original command:

openssl smime -encrypt -binary -aes256 -in file.cfg -out file.cfg.enc -outform der cert1 cert2

does three core things: encrypts raw binary content with AES-256, wraps that encrypted content in an S/MIME envelope using two recipient certificates, and outputs the result in DER format. Here's a practical, step-by-step breakdown with code:

Key Concepts to Align with OpenSSL

First, let's map each OpenSSL flag to its C# equivalent:

  • -binary: Treat input as raw binary (no text encoding/decoding) → Read the file as bytes directly.
  • -aes256: Use AES-256-CBC for symmetric encryption (OpenSSL's default mode for this command) → Specify the AES-256-CBC algorithm via its OID.
  • -outform der: Output the S/MIME message in DER (binary) format → Use the EnvelopedCms.Encode() method, which natively produces DER.
  • cert1 cert2: Encrypt for two recipients → Add both certificates to the S/MIME recipient collection.

Step-by-Step Implementation

We'll use the System.Security.Cryptography.Pkcs namespace (built into .NET) which handles S/MIME operations natively.

1. Load Recipient Certificates

First, load the two public certificates (they don't need private keys for encryption). C# supports loading both PEM and DER formatted certificates directly.

2. Encrypt Content & Package into S/MIME Envelope

The EnvelopedCms class manages the entire S/MIME encryption workflow: it generates a random AES key, encrypts your content with it, then encrypts that AES key with each recipient's public key.

Full Code Example

using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;

public class SmimeFileEncryptor
{
    public static void EncryptFile(string inputPath, string outputPath, string certPath1, string certPath2)
    {
        try
        {
            // Load the two recipient certificates
            var cert1 = new X509Certificate2(certPath1);
            var cert2 = new X509Certificate2(certPath2);

            // Read input file as raw binary (matches -binary flag)
            byte[] rawContent = File.ReadAllBytes(inputPath);

            // Initialize EnvelopedCms with the content to encrypt
            var envelopedCms = new EnvelopedCms(new ContentInfo(rawContent));

            // Add both certificates as recipients
            var recipients = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber);
            recipients.Add(new CmsRecipient(cert1));
            recipients.Add(new CmsRecipient(cert2));

            // Specify AES-256-CBC as the encryption algorithm (matches -aes256)
            // OID for AES-256-CBC: 2.16.840.1.101.3.4.1.42
            var aes256Algorithm = new AlgorithmIdentifier(new Oid("2.16.840.1.101.3.4.1.42"));
            envelopedCms.Encrypt(recipients, aes256Algorithm);

            // Export the encrypted message in DER format (matches -outform der)
            byte[] derEncryptedData = envelopedCms.Encode();

            // Write the result to the output file
            File.WriteAllBytes(outputPath, derEncryptedData);

            Console.WriteLine("Encryption completed successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error during encryption: {ex.Message}");
            throw;
        }
    }

    // Example usage
    public static void Main(string[] args)
    {
        EncryptFile("file.cfg", "file.cfg.enc", "cert1.pem", "cert2.pem");
    }
}

Important Notes

  • Certificate Formats: If your certificates are PEM files with headers (-----BEGIN CERTIFICATE-----), X509Certificate2 can load them directly in .NET Core 3.0+ and .NET 5+. For older frameworks, you may need to convert PEM to DER first, or use a helper to parse the PEM content.
  • Algorithm Compatibility: The OID 2.16.840.1.101.3.4.1.42 explicitly specifies AES-256-CBC, which matches OpenSSL's default behavior for the -aes256 flag.
  • Error Handling: The example includes basic error handling, but you'll want to expand this for production use (e.g., checking if files exist, validating certificates).

内容的提问来源于stack exchange,提问作者Andreas Krieger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:50:37