| Crates.io | sk_dkim |
| lib.rs | sk_dkim |
| version | 0.1.7 |
| created_at | 2025-12-01 12:53:07.997975+00 |
| updated_at | 2025-12-04 07:58:17.523768+00 |
| description | Deterministic DKIM key generation based on secret key / 基于密钥的确定性 DKIM 密钥生成 |
| homepage | https://github.com/js0-site/rust/tree/main/sk_dkim |
| repository | https://github.com/js0-site/rust.git |
| max_upload_size | |
| id | 1959745 |
| size | 59,275 |
sk_dkim is a Rust library designed to generate DomainKeys Identified Mail (DKIM) keys and DNS TXT records deterministically. Instead of managing and storing private key files for every domain, you can derive the necessary RSA 2048 keys on-the-fly using a single secret seed (Secret Key) combined with the domain name and selector.
This approach simplifies key management, especially for services managing DKIM for multiple domains, as it eliminates the need for stateful storage of private keys.
Technically, Ed25519 is superior to RSA in almost every way for DKIM:
RFC 8463, published in 2018, explicitly states that verifiers MUST implement Ed25519 verification. However, the reality of the email ecosystem in 2024/2025 is a disappointing display of non-compliance by the industry giants:
Despite the standard being over 6 years old, these major providers have effectively ignored the "MUST implement" clause for verification. While some experts recommend "dual signing" (signing with both RSA and Ed25519), this adds significant complexity and bloat to headers.
Because of this widespread lack of support, sk_dkim was forced to switch from Ed25519 to RSA 2048. We had to compromise on elegance and efficiency to ensure deliverability in the real world. It's a step backward in technology, but a necessary one for practical usage.
Add sk_dkim to your Cargo.toml:
[dependencies]
sk_dkim = { version = "0.1.5", features = ["pk"] }
Note: The
pkfeature is required to generate the formatted TXT record string.
use sk_dkim::Sk;
fn main() {
// Your secret seed (keep this safe!)
let secret_seed = "your_secret_seed_string";
// Initialize the generator with the seed
let sk = Sk::new(secret_seed);
let selector = "default";
let domain = "example.com";
// Generate the DKIM struct for the specific domain and selector
let dkim = sk.dkim(selector, domain);
// Get the DNS TXT record value
// Output format: v=DKIM1; k=rsa; p=...
println!("DKIM Record: {}", dkim.txt());
}
The core philosophy of sk_dkim is determinism.
Sk struct is initialized with a base secret seed. This seed initializes a BLAKE3 hasher.dkim(selector, domain) is called, the hasher is cloned and updated with the selector and domain.This process ensures that as long as the secret seed remains constant, the generated DKIM keys for any given domain will always be the same.
struct SkThe main entry point for key generation.
Sk::new(sk: impl AsRef<[u8]>) -> Self
Creates a new Sk instance using the provided secret seed.
Sk::dkim(&self, selector: impl AsRef<str>, domain: impl AsRef<str>) -> Dkim
Derives a Dkim instance for the specified selector (selector) and domain (domain).
struct DkimRepresents the generated DKIM key pair.
pub sk: rsa::RsaPrivateKey
The underlying RSA private key.
Dkim::txt(&self) -> String
(Requires pk feature)
Returns the formatted DKIM DNS TXT record string (e.g., v=DKIM1; k=rsa; p=...).
.
├── Cargo.toml # Project configuration and dependencies
├── readme/ # Documentation
│ ├── en.md # English README
│ └── zh.md # Chinese README
├── src/ # Source code
│ └── lib.rs # Library entry point and implementation
├── tests/ # Integration tests
│ └── main.rs # Usage demonstration and testing
└── test.sh # Test execution script
This project is an open-source component of js0.site ⋅ Refactoring the Internet Plan.
We are redefining the development paradigm of the Internet in a componentized way. Welcome to follow us:
sk_dkim 是一个 Rust 库,用于确定性地生成 DomainKeys Identified Mail (DKIM) 密钥和 DNS TXT 记录。无需为每个域名单独管理和存储私钥文件,只需使用一个主密钥种子 (Secret Key),结合域名和选择器 (Selector),即可实时派生出所需的 RSA 2048 密钥。
这种方法极大地简化了密钥管理,特别是对于需要为大量域名提供 DKIM 签名的服务,彻底消除了对私钥状态存储的需求。
从技术角度来看,Ed25519 在 DKIM 应用中几乎全方位优于 RSA:
RFC 8463 早在 2018 年 就已发布,其中明确规定验证者 必须 (MUST) 实现 Ed25519 验证。然而,到了 2024/2025 年,电子邮件生态系统的现状却是行业巨头们集体违规的失望展示:
尽管该标准已经发布超过 6 年,这些主要服务商实际上完全无视了验证方面的 "MUST implement" 条款。虽然一些专家建议 "双重签名"(同时使用 RSA 和 Ed25519 签名),但这会显著增加复杂性和邮件头的臃肿程度。
正是由于这种广泛的缺乏支持,sk_dkim 被迫从 Ed25519 切换回 RSA 2048。为了确保邮件在现实世界中的可达性,我们不得不牺牲优雅和效率。这是技术的倒退,但在当前环境下却是无奈且必须的选择。
在 Cargo.toml 中添加 sk_dkim:
[dependencies]
sk_dkim = { version = "0.1.5", features = ["pk"] }
注意:生成格式化的 TXT 记录字符串需要开启
pk特性。
use sk_dkim::Sk;
fn main() {
// 主密钥种子 (请务必妥善保管)
let secret_seed = "your_secret_seed_string";
// 使用种子初始化生成器
let sk = Sk::new(secret_seed);
let selector = "default";
let domain = "example.com";
// 为特定域名和选择器生成 DKIM 结构
let dkim = sk.dkim(selector, domain);
// 获取 DNS TXT 记录值
// 输出格式: v=DKIM1; k=rsa; p=...
println!("DKIM Record: {}", dkim.txt());
}
sk_dkim 的核心理念是确定性。
Sk 结构体使用基础的主密钥种子进行初始化。该种子用于初始化一个 BLAKE3 哈希器。dkim(selector, domain) 时,克隆哈希器并利用 selector 和 domain 更新哈希状态。此流程确保只要主密钥种子保持不变,对于给定的域名,生成的 DKIM 密钥将始终一致。
struct Sk密钥生成的主要入口点。
Sk::new(sk: impl AsRef<[u8]>) -> Self
使用提供的主密钥种子创建一个新的 Sk 实例。
Sk::dkim(&self, selector: impl AsRef<str>, domain: impl AsRef<str>) -> Dkim
为指定的选择器 (selector) 和域名 (domain) 派生一个 Dkim 实例。
struct Dkim表示生成的 DKIM 密钥对。
pub sk: rsa::RsaPrivateKey
底层的 RSA 私钥。
Dkim::txt(&self) -> String
(需要 pk 特性)
返回格式化的 DKIM DNS TXT 记录字符串 (例如 v=DKIM1; k=rsa; p=...)。
.
├── Cargo.toml # 项目配置与依赖
├── readme/ # 文档目录
│ ├── en.md # 英文说明文档
│ └── zh.md # 中文说明文档
├── src/ # 源代码
│ └── lib.rs # 库入口与实现
├── tests/ # 集成测试
│ └── main.rs # 使用演示与测试
└── test.sh # 测试执行脚本
本项目为 js0.site ⋅ 重构互联网计划 的开源组件。
我们正在以组件化的方式重新定义互联网的开发范式,欢迎关注: