#secret #logging #password #pii #no-std

no-std redact

一个简单的库,用于防止秘密出现在日志中

23 个版本

0.1.10 2024 年 5 月 11 日
0.1.9 2024 年 3 月 24 日
0.1.8 2024 年 1 月 25 日
0.1.7 2023 年 11 月 1 日
0.1.1-pre02023 年 2 月 5 日

编码 中排名 #142

Download history 7676/week @ 2024-04-30 10745/week @ 2024-05-07 9943/week @ 2024-05-14 9150/week @ 2024-05-21 8771/week @ 2024-05-28 10420/week @ 2024-06-04 8674/week @ 2024-06-11 6490/week @ 2024-06-18 7408/week @ 2024-06-25 7968/week @ 2024-07-02 6777/week @ 2024-07-09 10085/week @ 2024-07-16 10389/week @ 2024-07-23 10593/week @ 2024-07-30 10365/week @ 2024-08-06 9732/week @ 2024-08-13

每月下载 43,009
用于 3 crates

MIT/Apache

18KB
263

Redact

License Latest version Latest Docs downloads-badge

API 文档

一个简单的库,用于防止秘密出现在日志中。

Redact 提供了一个包装器,防止秘密出现在日志中。

use redact::Secret;

let encryption_key = Secret::new("hello world");
assert_eq!("[REDACTED &str]", format!("{encryption_key:?}"))

包装器内部的秘密只能通过 expose_secret 方法或 [expose_secret] 函数[^1] 来访问。

use redact::Secret;

let encryption_key = Secret::new("hello world");
assert_eq!("hello world", *encryption_key.expose_secret())

Secret 类型同时作为有用的文档工具。应小心记录维护者应小心处理的价值。

use redact::Secret;

#[derive(Debug)] // Safe since Debug is not able to "see" our `Secret`s
struct Payment {
    // The recipient is PII so we don't want it to appear in logs
    recipient: Secret<String>,
    // It's okay for the amount to appear in logs so we don't mark it with `Secret`
    amount: u64,
}

Serde 支持

为了启用 serde 支持,请确保在您的 Cargo.toml 中启用了 serde 功能。

redact = { version = "0.1", features = ["serde"] }

Deserialize 如预期工作,透明地反序列化包含的秘密。

由于序列化可能会暴露包含的秘密,因此只能使用 [expose_secret] 实现 Serialize

use redact::{Secret, expose_secret};
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Payment {
    #[serde(serialize_with = "expose_secret")]
    recipient: Secret<String>,
    amount: u64,
}

如果您想在不暴露 Secret 的情况下实现 Serialize,请参阅 serde::redact_secret

Zeroizing Secret

redact 不要求 Secret 是可 Zeroize 的,但允许当包含的秘密是可 Zeroize 的时,将 Secret Zeroize。要能够 Zeroize Secret,请在您的 Cargo.toml 中启用 zeroize

redact = { version = "0.1", features = ["zeroize"] }
zeroize = "1"

启用后,可以 Zeroize 秘密。

# use redact::Secret;
use zeroize::Zeroize;


fn main() {
    let mut secret = Secret::new("hunter2".to_owned());

    // [ ... ] use secret here

    // Now that we're done using the secret, zero it out.
    secret.zeroize();
    # assert_ne!(*secret.expose_secret(), "hunter2")
}

如果您希望当 Secret 不再被使用时自动 Zeroize,请考虑将您的 Secret 包装在 Zeroizing 中,当它 Drop 时将 Zeroize 您的秘密。

# use redact::Secret;
use zeroize::Zeroizing;


fn main() {
    let mut secret = Zeroizing::new(Secret::new("hunter2".to_owned()));

    // [ ... ] use secret here

    // The secret is automatically zeroed out at the end of the scope when it is dropped
}

与其他替代方案的比较

secrecy

Secrecy 是这个包的原型灵感,它有类似的 API。

一个显著的区别是,保密性要求所有秘密实现 Zeroize,以便在它们被丢弃后能够干净地擦除内存中的秘密。遗憾的是,这限制了可以包装在 Secret 中的值类型,因为每个类型都必须知道 Zeroize

Redact 放宽了这一要求,允许所有类型都成为 Secret。当需要零化时,考虑上述技术 以上

秘密

Secrets 通过使用 mlock(2)/mprotect(2) 等技术,提供了比 secrecy 更强的内存保护。如果在 Secret 被丢弃前后需要强大的内存保护,请考虑 secrets

[^1]: [Secret] 将假定将其秘密暴露给其包含的类型的 [Default],[Hash],[Copy],[Clone],[Ord],[PartialOrd],[Eq],[PartialEq],std::ops::Addstd::ops::AddAssignstd::ops::BitAndstd::ops::BitAndAssignstd::ops::BitOrstd::ops::BitOrAssignstd::ops::BitXorstd::ops::BitXorAssignstd::ops::Divstd::ops::DivAssignstd::ops::Mulstd::ops::MulAssignstd::ops::Remstd::ops::RemAssignstd::ops::Shlstd::ops::ShlAssignstd::ops::Shrstd::ops::ShrAssignstd::ops::Substd::ops::SubAssignstd::ops::Negstd::ops::Not

依赖项

~0–360KB