生产中的锈蚀:1个密码

2021-01-21 04:56:29

Rust席卷了编程语言世界。自2015年发布1.0版以来,它一直是最受欢迎的编程语言之一,得到了开发人员和贡献者的忠实拥护。

要了解为什么开发人员如此偏爱这种语言,我们开始了有关Rust在生产中的新系列。在其中,我们将采访使用Rust进行重大项目的人员:应用程序,服务,启动MVP等。

对于本系列的第一部分,我们采访1Password工程部副总裁Michael Fey。进一步阅读以了解他们为什么选择Rust作为其产品,为什么Rust对于以安全性为中心的应用程序有好处,以及如果您要在Rust中开发类似的东西,应该考虑使用哪些很棒的库。

1Password是一个密码管理器,受到数百万用户和70,000家企业的信任,以保护其敏感数据。它会记住您所有的密码,因此您无需记住它,并且随附适用于所有主要浏览器的应用程序,以及台式机和移动设备。

我是1Password的客户端应用程序工程副总裁。如果您曾经有幸在Mac,Windows PC,iPhone,iPad,Android手机或平板电脑上或在浏览器中使用1Password,那么您很幸运可以使用我们团队开发的产品。自2004年以来我们一直存在,我们为建立精心设计的体验并确保人们上网安全感到自豪。

您能谈谈1Password的堆栈吗?您的代码库有多少部分用Rust编写?

几年来,我们一直在1Password的生产环境中使用Rust。我们的Windows团队是这项工作的领先者,以至于大约70%的Windows 1Password 7是用Rust编写的。我们还将在2019年底将1Password Brain(为浏览器填充逻辑提供动力的引擎)从Go移植到Rust,以便我们可以在浏览器扩展中利用将Rust部署到WebAssembly的速度和性能。

这些已经投入生产了近几年,我们已经看到了巨大的成功。如此之多,以至于我们现在几乎完全重写了我们的整个产品阵容,而Rust是这个故事的重要组成部分。我们正在使用Rust创建一个无头的1Password应用程序,该应用程序包含所有业务逻辑,加密,数据库访问,服务器通信,以及包装在我们要部署的系统固有的瘦UI层中的更多内容。

最初吸引我们进入Rust的主要因素之一是内存安全性。知道Rust可以帮助我们最大程度地提高对客户机密安全性的信心,这无疑使我们感到兴奋。除了内存安全性之外,我们对Rust生态系统还有更多的爱。缺乏传统的运行时可显着提高性能;例如,我们不必担心垃圾收集器的开销。 Rust提供了一种“程序正确性”的形式,并提供了许多保证在运行时避免未定义行为的方法。强类型系统在编译时强制执行这些规则。仔细地使应用程序逻辑与Rust的强类型规则保持一致,将使API难以正确使用,并简化了代码,而无需进行运行时检查约束和不变式;编译器可以保证没有无效的运行时代码路径,这些路径会在程序执行之前使您的程序误入歧途。不必执行更少的运行时状态验证就可以产生更简洁,更高效,更专注和更高质量的代码。与其他语言相比,Rust需要很少的运行时调试。如果可以编译,则可以肯定它不会表现出意外的行为。它可能不是您想要的,但将是“正确的”。 🙂

Rust的另一个非常强大(经常被忽略)的功能是它的过程宏系统,它使我们能够编写一种工具来自动与客户端语言(Swift,Kotlin和TypeScript)共享Rust中定义的类型。该工具的输出会自动处理序列化/反序列化过程,这意味着我们的客户端开发人员在与Rust库进行交互时可以继续使用他们选择的语言工作,并且无需担心通过外部函数接口进行JSON解析( FFI)。我们得到了所有这些,同时享受了我们每种目标语言中的编译时类型检查的好处。我们也已将此工具集成到我们的持续集成服务器中,这意味着对Rust模型的更改可能会导致在审核过程中捕获到的客户端应用程序编译失败。

该工具已成为我们开发过程中不可或缺的组成部分,使我们能够比以往更快地移动。一旦在Rust中定义了我们的类型,我们就可以立即用客户端语言生成等效的类型。这使我们的开发人员可以专注于解决问题,而无需手动编写样板代码以通过FFI进行通信。

Rust对开发以安全性为中心的应用程序(如1Password)的支持(库或其他)有多好?

有足够的能力来建立以安全为中心的应用程序所需的大部分基础。有两个大型的,突出的加密平台(ring和Rust Crypto组)一起提供了很多功能。正如我上面提到的,使用Rust本身进行编写可以使您对内存使用有更大的信心,并且使向应用程序中意外引入与内存相关的漏洞更加困难。还有一个完善的系统可以跟踪不时出现在Rust板条箱中的漏洞:RustSec数据库,该数据库由其他Rust开发人员提供社区资源,并经常使用可在其中使用的新信息进行更新。 CI审核扫描。 Rust和Cargo还包括电池测试框架,这意味着您总是有一种简便的方法来编写单元测试套件,以确保关键代码(例如您编写的任何加密函数)的正确行为。

尽管安全的本机Rust库是梦dream以求的(它们会及时出现),但始终可以选择使用C或本机平台库中的内容并轻松使用。我们将其用于Rust代码中,以实现诸如调用生物识别解锁的本地实现(触摸ID,面部ID,Windows Hello)和特定于平台的设置实现(例如Apple平台上的NSUserDefaults)之类的功能。

绝对。 Tokio,Hyper / Reqwest,Ring和Neon都在1Password中拥有一席之地,对于让我们完全解决这个雄心勃勃的项目至关重要。您还应该在crates.io上查看我们的password-rules-parser,它基于主要由Apple支持的规范。他们的工具和文档可以在这里找到。

Rust在哪里最适合使用,在堆栈中何处不足?

当我们开始这个项目时,Rust已经实现了我们期望的90%。我们已经能够以某种形式将其部署到几乎每个目标平台上(Apple Watch除外)。语言本身的设计具有现代感,并且每次发布时都在不断改进。它具有出色的文档资料和活跃的社区。

尽管有数不尽的板条箱可供使用,但我们还是必须推出自己的日志记录和跟踪工具,以确保在1Password中可以安全使用。此外,我们构建了一个实质性的本地化实施方案,以满足我们产品的需求。

它确实在一个关键方面不足以帮助我们:我们希望WebAssembly可以使我们在浏览器和浏览器扩展方面比它更进一步。 WebAssembly作为功能库非常出色,但是尝试在WASM中支持整个运行时一直是一个挑战。但是,我们遇到的许多问题不是Rust的局限性,而是WebAssembly作为部署平台的局限性。

我们团队中的许多人都是Rust的新手,他们经历了内存管理和所有权模型附带的典型学习曲线。我们还发现编译时间非常强大。我们的CPU和风扇肯定会锻炼。 😄

如果您不熟悉Rust,请从小处着手并以此为基础。当我们开始尝试寻找基于Rust的解决方案所能提供的优势时,我们进行了大量实验。当实验顺利进行时,请尝试重新想象一下您以前与其他语言一起工作的方式,看看您的代码是否可以从Rust的哲学中受益。

如果您不熟悉1Password,可以立即使用此链接注册,并为家庭和个人帐户节省第一年50%的费用。 如果您从事的是开源项目,则可以免费获得1Password Teams帐户。 前往我们的GitHub存储库以了解更多信息。 我要感谢Michael的采访,并祝1Password在创建最出色的密码管理器中万事如意! 要阅读有关Rust之类的编程语言的更多信息,请确保在Medium,DEV或Twitter上关注我们。 如果您正在寻找下一篇文章,我们还有一篇有关9个其他Rust生产故事的文章,您可能想看看。