首页 > 解决方案 > 如何在 Rust 中编写 S/MIME 加密消息?

问题描述

有这么多可用的板条箱,我怀疑用于编写加密 S/MIME 消息的板条箱会丢失。我知道pgp应该处理 PGP/MIME。我也知道lettre_email emailmessagemailparse mail-core可用于撰写 MIME 电子邮件消息...

如果没有,我在问是否有人已经这样做了,所以我可以复制 cat 并可能发布。否则我将自己与它作斗争,并会欣赏一个良好的开端。

目标是加密存储在邮件服务器Samotop上的静态消息。知道收件人的公钥后,我应该能够对该收件人的任何传入消息进行包装加密,以便只有拥有该密钥的用户才能解密该消息。很可能 S/MIME 不适合这种情况,但我希望它可以与支持 S/MIME 的现有电子邮件客户端一起使用。

首先,我想会有一个加密消息的对称密钥,并且这个密钥将使用非对称密钥为接收者(可能是多个接收者)加密并包含在有效负载中。这是我的想法的草图

生成随机对称密钥:

    let mut key = [0u8; 32];
    SystemRandom::new().fill(&mut key).unwrap();

内容被加密:

    // Sealing key used to encrypt data
    let mut sealing_key = SealingKey::new(
        UnboundKey::new(&CHACHA20_POLY1305, key.as_ref()).unwrap(),
        Nonces::new(5),
    );

    // Encrypt data into in_out variable
    sealing_key
        .seal_in_place_append_tag(Aad::empty(), &mut encrypted)
        .unwrap();

对称密钥对接收者进行非对称加密:

    let enc_key = pub_key.encrypt(&mut rng, PaddingScheme::new_pkcs1v15_encrypt(), &key[..]).expect("failed to encrypt");
    assert_ne!(&key[..], &enc_key[..]);

现在是编写加密 MIME 部分的时候了……想法?板条箱?参考实现?RFC8551

标签: emailrustcryptographypublic-key-encryptionsmime

解决方案


到目前为止,我发现的唯一现成的解决方案是openssl binding。它有一个 Pkcs7 结构,应该能够encrypt()sign()并产生 mime 部分to_smime()

这是来自 openssl 存储库的稍作修改的测试:

        let cert = X509::from_pem(CERT)?;
        let mut certs = Stack::new()?;
        certs.push(cert.clone())?;

        let flags = Pkcs7Flags::STREAM;
        let message = b"secret stuff";

        let pkcs7 = Pkcs7::encrypt(&certs.as_ref(), message, Cipher::aes_256_cbc(), flags)?;

        let encrypted = pkcs7.to_smime(message, flags).expect("should succeed");


推荐阅读