2key-ratchet 中文文档教程

发布于 4年前 浏览 29 项目主页 更新于 3年前

2key-ratchet

CircleCI许可证覆盖状态npm 版本

NPM

2key-ratchetDouble Ratchet 的一个实现使用 WebCrypto 的 TypeScript 中的协议和 X3DH

Double Ratchet 协议和 X3DH 的设计目标是提供前向保密和密码可否认性。 重要的是,有几项独立的安全审查得出的结论是它们实现了这些目标。

术语“双棘轮”来自协议如何确保每条消息获得一个新密钥:他们的 Diffie-Hellman 密钥由每次新消息交换“棘轮化”; 发送/接收链也是如此(“symmetric-key ratchet”)。

原始规范和 2key-ratchet,最重要的是,正如它的名字所暗示的,它使用L19">两把钥匙,一把用于身份验证,另一把用于密钥交换。 另一个重要的是使用 secp256r1 而不是 curve25519,因为浏览器本身还不支持这条曲线。

请参阅ARCHITECTURE 文档以更好地了解库结构。

有关可以在何处使用 2key-ratchet 的想法,请参阅场景文件。

有关许可信息,请参阅 LICENSE 文件。

Overview

IdentityKeys

协议中的每个对等点都有一个 IdentityKey,这些是 secp256r1 密钥。 这些密钥用于验证 PreKeysExchangeKeysIdentityKeys 的使用类似于 X.509 证书中的公钥。

ExchangeKeys

ExchangeKeys 由 2key-ratchet 引入,它们用于派生 PreKeysExchangeKey 由同级 IdentityKey 签名。

PreKeys

2key-ratchet 中,PreKey 是一个带有关联唯一 ID 的 secp256r1 公钥。 这些 PreKeysIdentityKey 签名。

首次使用时,客户端会生成一个已签名的 PreKey,以及大量未签名的 PreKey,并将它们全部传输到服务器。

Server

协议中的服务器是一个不受信任的实体,它只是存储预密钥,以便在对等方可能离线且无法访问时进行检索。

Sessions

双棘轮协议是面向会话的。 对等点彼此建立一个会话,然后用于所有后续交换。 这些会话可以保持打开状态并重新使用,因为每条消息都使用新的唯一加密密钥进行加密。

Size and Dependencies

NameSizeDescription
2key-ratchet.js66 KbUMD module without external modules

注意:您还必须导入 tslibprotobufjs 在浏览器中使用。

Instructions

Installation

npm install 2key-ratchet

Usage

在您的应用程序中包含 2key-ratchet 及其依赖项。

NODEJS:

let DKeyRatchet = require("2key-ratchet");

浏览器:

<script src="2key-ratchet.js"></script>

DKeyRatchet 命名空间将始终在全球范围内可用,并且还支持 AMD 加载程序。

Generate an IdentityKey

第一步是创建一个 IdentityKey。

let AliceID;
DKeyRatchet.Identity.create(16453, 1, 1)
    .then((id) => {
        AliceID = id;
    });

然后创建您的 PreKey 消息包:

let bundle = new DKeyRatchet.PreKeyBundleProtocol();

bundle.identity.fill(AliceID)
    .then(() => {
        bundle.registrationId = AliceID.id;
        const preKey = AliceID.signedPreKeys[0];
        bundle.preKeySigned.id = 1;
        bundle.preKeySigned.key = preKey.publicKey;
        return bundle.preKeySigned.sign(AliceID.signingKey.privateKey);
    })
    .then(() => {
        return bundle.exportProto();
    })
    .then((ab) => {
        console.log(ab); // ArrayBuffer { byteLength: 374 }
    });

然后导入生成的 PreKey 消息包:

DKeyRatchet.PreKeyBundleProtocol.importProto(ab)
    .then((bundle) => {
        // check signed prekey
        return bundle.preKeySigned.verify(AliceID.signingKey.publicKey);
    })
    .then((trusted) => {
        if (!trusted)
            throw new Error("Error: The PreKey is not trusted");
    })

Create a session

完成前面的步骤后,您现在可以创建一个会话:

注意:使用模块 pvtsutils 进行数据转换。

DKeyRatchet.AsymmetricRatchet.create(BobID, bundle)
    .then((cipher) => {
        return cipher.encrypt(Convert.FromUtf8String("Hello world!"));
    })
    .then((preKeyMessage) => {
        return preKeyMessage.exportProto();
    })
    .then((BobMessage) => {
        console.log(BobMessage); // ArrayBuffer {byteLength: 408}
    });

另一方面,您也可以这样做:

// Parse received bytes to proto
return DKeyRatchet.PreKeyMessageProtocol.importProto(BobMessage)
    .then((proto) => {
        return DKeyRatchet.AsymmetricRatchet.create(AliceID, proto)
            .then((cipher) => {
                return cipher.decrypt(proto.signedMessage);
            })
            .then((message) => {
                console.log(Convert.ToUtf8String(message)); // Hello world!
            });
    });

我们有一个完整示例,您可以在此处查看。

Contributing

如果您发现 2key-ratchet 有问题,请打开一个新问题。 也欢迎功能请求。

拉取请求——补丁、改进、新功能——是一个了不起的帮助。 在开始任何重要的拉取请求(例如,实施新功能)之前,请先询问。

Note

Bruce Schneier 有一句名言:“如果你认为密码学可以解决你的问题,那么你就没有理解你的问题,你也不了解密码学”。 关键是,使用 2key-ratchet 或任何其他“加密相关”库不一定会使您的产品安全。

简而言之,制作安全产品远不止添加密码学,这是一个让您熟悉防御性思维的好书

WARNING

尽管此库基于双棘轮算法X3DH 密钥协议几个变化已经做出可以改变他们提供的安全属性。 此时,您应该考虑将此实现适合于进行实验,直到完成进一步的安全审查。

Acknowledgements

Double Ratchet 和 X3DH 均由 Trevor Perrin 和 Moxie Marlinspike 设计,我们感谢他们的工作。

2key-ratchet

CircleCILicenseCoverage Statusnpm version

NPM

2key-ratchet is an implementation of a Double Ratchet protocol and X3DH in TypeScript utilizing WebCrypto.

The Double Ratchet protocol and X3DH were designed with goals of providing both forward secrecy and cryptographic deniability. Importantly there have been several independent security reviews that concluded they deliver on those goals.

The term “Double Ratchet” comes from how the protocol makes sure each message gets a new key: their Diffie-Hellman keys are “ratcheted” by each new message exchange; and so are the send/receive chains (the “symmetric-key ratchet”).

There are a few differences between the original specifications and 2key-ratchet, the most significant being, as it’s name suggests, it uses two keys, one for authentication and another for key exchange. The other big one is that secp256r1 is used instead of curve25519 because browsers do not yet support this curve natively.

See the ARCHITECTURE document to better understand the library structure.

For ideas on where you might use 2key-ratchet see the SCENARIOS document.

For licensing information, see the LICENSE file.

Overview

IdentityKeys

Each peer in the protocol has an IdentityKey, these are secp256r1 keys. These keys are used to authenticate both PreKeys and ExchangeKeys. IdentityKeys are used similarly to the public key in an X.509 certificate.

ExchangeKeys

ExchangeKeys are introduced by 2key-ratchet, they are used to derive PreKeys. The ExchangeKey is signed by a peers IdentityKey.

PreKeys

In 2key-ratchet a PreKey is a secp256r1 public key with an associated unique id. These PreKeys are signed by the IdentityKey.

On first use, clients generate a single signed PreKey, as well as a large list of unsigned PreKeys, and transmit all of them to a server.

Server

The server in the protocol is an untrusted entity, it simply stores preKeys for retrieval when the peer may be offline and unreachable.

Sessions

The Double Ratchet protocol is session-oriented. Peers establish a session with each other, this is then used for all subsequent exchanges. These sessions can remain open and be re-used since each message is encrypted with a new and unique cryptographic key.

Size and Dependencies

NameSizeDescription
2key-ratchet.js66 KbUMD module without external modules

NOTE: You will also have to import tslib and protobufjs for use in the browser.

Instructions

Installation

npm install 2key-ratchet

Usage

Include 2key-ratchet and its dependencies in your application.

NODEJS:

let DKeyRatchet = require("2key-ratchet");

BROWSER:

<script src="2key-ratchet.js"></script>

The DKeyRatchet namespace will always be available globally and also supports AMD loaders.

Generate an IdentityKey

The first step is to create an IdentityKey.

let AliceID;
DKeyRatchet.Identity.create(16453, 1, 1)
    .then((id) => {
        AliceID = id;
    });

Then create your PreKey message bundle:

let bundle = new DKeyRatchet.PreKeyBundleProtocol();

bundle.identity.fill(AliceID)
    .then(() => {
        bundle.registrationId = AliceID.id;
        const preKey = AliceID.signedPreKeys[0];
        bundle.preKeySigned.id = 1;
        bundle.preKeySigned.key = preKey.publicKey;
        return bundle.preKeySigned.sign(AliceID.signingKey.privateKey);
    })
    .then(() => {
        return bundle.exportProto();
    })
    .then((ab) => {
        console.log(ab); // ArrayBuffer { byteLength: 374 }
    });

And then import the generated PreKey message bundle:

DKeyRatchet.PreKeyBundleProtocol.importProto(ab)
    .then((bundle) => {
        // check signed prekey
        return bundle.preKeySigned.verify(AliceID.signingKey.publicKey);
    })
    .then((trusted) => {
        if (!trusted)
            throw new Error("Error: The PreKey is not trusted");
    })

Create a session

With the previous steps complete you can now create a session:

NOTE: For data conversion was used module pvtsutils.

DKeyRatchet.AsymmetricRatchet.create(BobID, bundle)
    .then((cipher) => {
        return cipher.encrypt(Convert.FromUtf8String("Hello world!"));
    })
    .then((preKeyMessage) => {
        return preKeyMessage.exportProto();
    })
    .then((BobMessage) => {
        console.log(BobMessage); // ArrayBuffer {byteLength: 408}
    });

On the other side you would do the same:

// Parse received bytes to proto
return DKeyRatchet.PreKeyMessageProtocol.importProto(BobMessage)
    .then((proto) => {
        return DKeyRatchet.AsymmetricRatchet.create(AliceID, proto)
            .then((cipher) => {
                return cipher.decrypt(proto.signedMessage);
            })
            .then((message) => {
                console.log(Convert.ToUtf8String(message)); // Hello world!
            });
    });

We have a complete example you can look at here.

Contributing

If you've found an problem with 2key-ratchet, please open a new issue. Feature requests are welcome, too.

Pull requests – patches, improvements, new features – are a fantastic help. Please ask first before embarking on any significant pull request (e.g., implementing new features).

Note

Bruce Schneier famously said "If you think cryptography can solve your problem, then you don't understand your problem and you don't understand cryptography". The point being, using 2key-ratchet, or any other "cryptography related" library, will not necessarily make your product secure.

In short, there is a lot more to making a secure product than adding cryptography, this is a great book to get you familiar with thinking defensively.

WARNING

Though this library is based on the Double Ratchet Algorithm and the X3DH Key Agreement Protocol several changes have been made that could change the security properties they offer. At this time you should consider this implementation appropriate for experimentation until further security reviews are completed.

Acknowledgements

Both Double Ratchet and X3DH were designed by Trevor Perrin and Moxie Marlinspike, we thank them for their work.

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文